`
feisuzhu
  • 浏览: 14394 次
  • 性别: Icon_minigender_1
  • 来自: 济南
最近访客 更多访客>>
文章分类
社区版块
存档分类
最新评论

PyPy中的extendabletype与pairtype解析

 
阅读更多

# -*- coding: utf-8 -*- 

# 首发在 http://page.renren.com/601001752/note/775449636
''' 
PyPy中的extendabletype与pairtype解析 

玩过C#的同学都知道,C#中有一个partial关键字,可以将一个类的实现分在多个文件中,最后由编译器组合起来。这样可以实现多人协作,分离手写和自动生成的代码。 

可能有人会抱怨,为什么Python没有提供这种功能呢?其实是提供了的,只不过比较隐蔽而已——这种问题可以使用元类(metaclass)来解决~ 

什么是元类呢?用一句话来说,元类就是类的类,一般的类是元类的实例。Python下可以使用type(obj)来获得一个变量的类型。type(一个类的实例)会返回那个类,type(一个类)则会返回这个类的元类。在不指明元类的情况下,旧版类的元类是classobj,新版类的元类就是type。这里有一个很有趣的事实:type的元类还是type,type的基类是object,object的元类是type…… 

说了这么多不相关的,到底PyPy的代码是怎样实现partial class的呢? 请看pypy/tool/pairtype.py: 
''' 

class extendabletype(type): 
    """A type with a syntax trick: 'class __extend__(t)' actually extends 
the definition of 't' instead of creating a new subclass.""" 
    def __new__(cls, name, bases, dict): #当创建新类的时候,调用这个函数。此时cls相当与self,不过指的是当前的元类;name是新类的名字;bases是新类的基类;dict是新类的内容,也就是class定义后的那些东西,函数,类变量等等。 
        if name == '__extend__': 
            for cls in bases: 
                for key, value in dict.items(): 
                    if key == '__module__': 
                        continue 
                    # XXX do we need to provide something more for pickling? 
                    setattr(cls, key, value) 
            return None 
        else: 
            return super(extendabletype, cls).__new__(cls, name, bases, dict# 相当于type.__new__(xxxx) 
             
''' 
可以看出,这个元类实现的功能很简单:如果新类的名字是'__extend__',那么不创建新类,而是把新类的dict合并到基类中,这样就相当与扩充了基类! 
举个例子: 
''' 

class MyClass(object): 
    __metaclass__ = extendabletype 
     
    def myprint1(): 
        print "Proton rocks!" 

class __extend__(MyClass): 
    def myprint2(): 
        print "Proton really rocks!" 

#与 

class MyClass(object): 
     
    def myprint1(): 
        print "Proton rocks!" 

    def myprint2(): 
        print "Proton really rocks!" 
         
''' 
是完全一样的! 
知道了这些,就留个小的练习吧: C#中的sealed关键字(不能被继承)在Python中怎么实现呢?只要发现违规用法报错就可以。 

pairtype则是一个更有趣的东西:它的目的是将两个类组合在一起,来作为一个新的类。这么说很容易让人产生误解,还是看源码吧~ 
''' 

def pair(a, b): 
    """Return a pair object.""" 
    tp = pairtype(a.__class__, b.__class__) #根据a和b的类找到相应的pairtype 
    return tp((a, b)) # tp is a subclass of tuple, 根据a和b创建pairtype的实例 

pairtypecache = {} 

def pairtype(cls1, cls2):  
    """type(pair(a,b)) is pairtype(a.__class__, b.__class__).""" 
    try: 
        pair = pairtypecache[cls1, cls2] # 如果pairtype已经存在,就直接返回 
    except KeyError# 如果不存在,就创建一个相应的类 
        name = 'pairtype(%s%s)' % (cls1.__name__, cls2.__name__) 
        bases1 = [pairtype(base1, cls2) for base1 in cls1.__bases__] # 寻找所有的基类,比如pairtype(Human, Girl) 和 pairtype(Boy, Human)就应该是pairtype(Boy, Girl)的基类 
        bases2 = [pairtype(cls1, base2) for base2 in cls2.__bases__] 
        bases = tuple(bases1 + bases2) or (tuple,) # 'tuple': ultimate base 
        pair = pairtypecache[cls1, cls2] = extendabletype(name, bases, {}) # <- 注意是extendabletype,不是type哦 
    return pair 
''' 
恩 这个东西有什么好玩的呢? 在这里举个例子: 
''' 
class Human(object): 
    def __init__(self, name): 
       self.name = name 

class Boy(Human): pass 
class Girl(Human): pass 

class __extend__(pairtype(Human, Human)): 
    def talk((a, b)): # 注意pairtype的基类是tuple, 所以可以直接这样写 
        print "%s and %s are talking." % (a.name, b.name) 

class __extend__(pairtype(Boy, Boy)): 
    def duel((a, b)): 
        print "%s and %s try to prove they are real men, decided to duel." % (a.name, b.name) 

class __extend__(pairtype(Girl, Girl)): 
    def unlimited_talk((a, b)): 
        print "Girls are really scary, %s and %s kept talking for hours without drinking a single gulp of water." % (a.name, b.name) 

class __extend__(pairtype(Boy, Girl), pairtype(Girl, Boy)): 
    def makelove((a, b)): 
        print "%s and %s are... hey you knew it!" % (a.name, b.name) 

reimu = Girl("Reimu") 
marisa = Girl("Marisa") 
moku = Boy("Moku") 
rinnosuke = Boy("Rinnosuke") 

cp1 = pair(reimu, marisa) 
cp1.talk() 
cp1.unlimited_talk() 

cp2 = pair(moku, rinnosuke) 
cp2.talk() 
cp2.duel() 

cp3 = pair(rinnosuke, reimu) 
cp3.talk() 
cp3.makelove()

分享到:
评论

相关推荐

    pypy windows 最新版 v5.8.0

    - **环境变量配置**: 安装完成后,可能需要将 PyPy 的 bin 目录添加到系统环境变量 PATH 中,以便在命令行中直接运行 PyPy。 - **测试运行**: 可以通过运行 `pypy.exe` 文件来启动 PyPy 解释器,并输入简单的 ...

    pypy.tar.gz

    这种动态编译技术可以优化掉许多Python解释器中的开销,如动态类型检查和运行时的字节码解析。 **PyPy的RPython** PyPy的实现基于一种称为“Restricted Python”或RPython的子集。RPython是一种受到限制的Python...

    pypy-2.6.1-win32

    - 一旦安装完成并配置了 PATH,用户可以在命令行中输入 `pypy` 来启动 PyPy 解释器,与使用 CPython 的 `python` 命令类似。 - PyPy 支持大部分 Python 2.7 的语法和库,因此已有的 Python 2.7 代码通常可以直接在...

    PyPy2 v590 Python 2.7.13

    与CPython的区别可以去看它的兼容性页面. PyPy还提供了JIT编译器和沙盒功能,因此运行速度比CPython要快,以及可以安全的运行一些不被信任的代码。PyPy还有一个单独的支持微线程的版本。 另外,PyPy 也有 每夜构建 ...

    pypy_get_pip-master.zip

    标题 "pypy_get_pip-master.zip" 暗示了这是一个与PyPy和pip相关的项目,主要用于在PyPy环境中安装pip。PyPy是Python的一个替代实现,它具有自己的JIT(Just-In-Time)编译器,以提高代码执行速度。而pip是Python的...

    pypy3-v6.0.0-win32

    1. **PyPy与CPython的区别**:PyPy 是一个使用RPython语言编写,具有JIT编译器的Python实现,其目标是速度和兼容性。与CPython相比,PyPy通常在执行速度上有显著提升,特别是在处理循环和大量数据时。 2. **JIT...

    Python-jitpyCPython中嵌入PyPy的库瞬间提速20x

    本文将深入讨论`jitpy`库,它是如何在CPython(Python的标准实现)中嵌入PyPy(一个优化的Python解释器),以及如何通过这种方式实现性能的显著提升。 `jitpy`是一个开源库,它的主要目标是让开发者能够在CPython...

    pypy3-v5.10.1-win32

    将该文件所在的目录添加到系统的PATH环境变量中,即可在命令行中直接运行PyPy。例如,通过命令`pypy3 your_script.py`来执行Python脚本。 **适用场景** 1. **性能敏感的项目**:当需要在Python环境中执行大量计算...

    windows最新版 pypy

    与传统的解释器不同,Pypy的JIT不是在程序运行前进行静态编译,而是在运行时动态编译经常执行的代码片段。这种技术可以显著提高代码的执行效率,尤其是在循环和递归等复杂计算场景下,使得Python代码的运行速度接近...

    pypy3.6-v7.1.1-win32.zip

    与CPython不同,Pypy使用了一种称为“轻量级虚拟机”的技术,这种技术允许更快的代码解析和执行。Pypy还使用了一种称为“垃圾回收”的内存管理策略,该策略比CPython的垃圾回收更高效,减少了内存占用和延迟。 Pypy...

    pypy3.6-v7.3.1-src.zip

    3. **src** 目录:包含了PyPy解释器的主要源代码,包括Python解释器的实现、JIT编译器以及CFFI(C Foreign Function Interface),用于与C库交互。 4. **rpython** 目录:RPython是PyPy使用的特殊编程子集,用于...

    使用最新PyPy代替CPython,加速Python执行

    Python官方的解释器是CPython,执行速度较慢,网上目前有许多PyPy和CPython的性能对比,PyPy比CPython快近25倍。原因是PyPy采用了先进的JIT编译器优化。  官网上的对比图:  先不扯淡了,知道你们可能听不懂。拐入...

    Pypy解释器

    1. **CFFI(C Foreign Function Interface)**: Pypy提供了CFFI,使得在Python中调用C库变得非常方便,进一步增强了Pypy的扩展性。 2. **垃圾收集**:Pypy采用了一种名为“混合垃圾收集”的策略,结合了引用计数和...

    pypy(Python语言动态编译器) v2.3.1 官方绿色版.zip

    PyPy的实现与原理 PyPy的第一部分:用Python实现的Python 其实这么说并不准确,准确得说应该是用rPython实现的Python,rPython是Python的一个子集,虽然rPython不是完整的Python,但用rPython写的这个Python实现却是...

    pypy3.6-v7.3.2-win32.zip

    安装和使用PyPy3.6-v7.3.2-win32时,你需要解压这个压缩包到一个适当的目录,然后可以通过解压目录下的`bin`目录中的`pypy3.exe`或`pypy3`命令行脚本来启动PyPy解释器。这允许你像使用常规Python那样运行Python程序...

    numpy-2.1.0rc1-pp310-pypy310_pp73-win_amd64.whl

    numpy-2.1.0rc1-pp310-pypy310_pp73-win_amd64.whl numpy-2.1.0rc1-pp310-pypy310_pp73-win_amd64.whl numpy-2.1.0rc1-pp310-pypy310_pp73-win_amd64.whl numpy-2.1.0rc1-pp310-pypy310_pp73-win_amd64.whl numpy-...

    GDAL-3.8.2-pp310-pypy310_pp73-win_amd64.whl.zip

    《GDAL库在Python环境中的应用与安装》 GDAL(Geospatial Data Abstraction Library)是一个开源的地理空间数据处理库,它提供了对多种遥感和地图数据格式的读取、写入和转换功能。在给定的文件“GDAL-3.8.2-pp310-...

    pypy3.7-v7.3.7-win64.zip

    PyPy 是用 Python 实现的 Python 解释器。PyPy 是 Python开发者为了更好的Hack Python创建的项目。此外,PyPy比CPython是更加灵活,易于使用和试验,以制定具体的功能在不同情况的实现方法,可以很容易实施。 该项目...

    pypy2-v6.0.0

    pypy2-v6.0.0,pypy最新版压缩包,是Python2.7替代产品,支持大多数的常用python标准包

Global site tag (gtag.js) - Google Analytics