python 元类、实现ORM( 二 )

4. 使用type创建带有属性的类type 接受一个字典来为类定义属性,因此
>>> Foo = type('Foo', (), {'bar': True})可以翻译为:
>>> class Foo(object):… bar = True并且可以将Foo当成一个普通的类一样使用:
>>> print(Foo)<class '__main__.Foo'>>>> print(Foo.bar)True>>> f = Foo()>>> print(f)<__main__.Foo object at 0x8a9b84c>>>> print(f.bar)True当然,你可以继承这个类,代码如下:
>>> class FooChild(Foo):… pass就可以写成:
>>> FooChild = type('FooChild', (Foo,), {})>>> print(FooChild)<class '__main__.FooChild'>>>> print(FooChild.bar) # bar属性是由Foo继承而来True注意:
type的第2个参数,元组中是父类的名字,而不是字符串
添加的属性是类属性,并不是实例属性
5. 使用type创建带有方法的类最终你会希望为你的类增加方法 。只需要定义一个有着恰当签名的函数并将其作为属性赋值就可以了 。
添加实例方法
In [46]: def echo_bar(self): # 定义了一个普通的函数 ...: print(self.bar) ...:In [47]: FooChild = type('FooChild', (Foo,), {'echo_bar': echo_bar}) # 让FooChild类中的echo_bar属性,指向了上面定义的函数In [48]: hasattr(Foo, 'echo_bar') # 判断Foo类中 是否有echo_bar这个属性Out[48]: FalseIn [49]:In [49]: hasattr(FooChild, 'echo_bar') # 判断FooChild类中 是否有echo_bar这个属性Out[49]: TrueIn [50]: my_foo = FooChild()In [51]: my_foo.echo_bar()True添加静态方法
【python 元类、实现ORM】In [36]: @staticmethod ...: def test_static(): ...: print("static method ....") ...:In [37]: Foochild = type('Foochild', (Foo,), {"echo_bar": echo_bar, "test_static": test_static})In [38]: fooclid = Foochild()In [39]: fooclid.test_staticOut[39]: <function __main__.test_static>In [40]: fooclid.test_static()static method ....In [41]: fooclid.echo_bar()True添加类方法
In [42]: @classmethod ...: def test_class(cls): ...: print(cls.bar) ...:In [43]:In [43]: Foochild = type('Foochild', (Foo,), {"echo_bar":echo_bar, "test_static": test_static, "test_class": test_class})In [44]:In [44]: fooclid = Foochild()In [45]: fooclid.test_class()True你可以看到,在Python中,类也是对象,你可以动态的创建类 。这就是当你使用关键字class时Python在幕后做的事情,而这就是通过元类来实现的 。
较为完整的使用type创建类的方式:
class A(object): num = 100def print_b(self): print(self.num)@staticmethoddef print_static(): print("----haha-----")@classmethoddef print_class(cls): print(cls.num)B = type("B", (A,), {"print_b": print_b, "print_static": print_static, "print_class": print_class})b = B()b.print_b()b.print_static()b.print_class()# 结果# 100# ----haha-----# 1006. 到底什么是元类(终于到主题了)元类就是用来创建类的“东西” 。你创建类就是为了创建类的实例对象,不是吗?但是我们已经学习到了Python中的类也是对象 。
元类就是用来创建这些类(对象)的,元类就是类的类,你可以这样理解为:
MyClass = MetaClass() # 使用元类创建出一个对象,这个对象称为“类”my_object = MyClass() # 使用“类”来创建出实例对象你已经看到了type可以让你像这样做:
MyClass = type('MyClass', (), {})这是因为函数type实际上是一个元类 。type就是Python在背后用来创建所有类的元类 。现在你想知道那为什么type会全部采用小写形式而不是Type呢?好吧,我猜这是为了和str保持一致性,str是用来创建字符串对象的类,而int是用来创建整数对象的类 。type就是创建类对象的类 。你可以通过检查__class__属性来看到这一点 。Python中所有的东西,注意,我是指所有的东西——都是对象 。这包括整数、字符串、函数以及类 。它们全部都是对象,而且它们都是从一个类创建而来,这个类就是type 。
>>> age = 35>>> age.__class__<type 'int'>>>>>>> name = 'bob'>>> name.__class__<type 'str'>>>>>>> def foo(): pass>>>foo.__class__<type 'function'>>>>>>> class Bar(object): pass>>> b = Bar()>>> b.__class__<class '__main__.Bar'>>>>现在,对于任何一个__class__的__class__属性又是什么呢?
>>> a.__class__.__class__<type 'type'>>>> age.__class__.__class__<type 'type'>>>> foo.__class__.__class__<type 'type'>>>> b.__class__.__class__<type 'type'>


推荐阅读