Python-metaclass

Python中类的概念

在理解什么是metaclass之前,先让我们了解一下Python中的普通类。Python对于什么是类有一个很特殊的概念。

在大多数的语言中,类就是一段代码,是用来创建对象的,这对Python也一样。例如:

class ObjectCreator(object):
    pass

my_object = ObjectCreator()
print(my_object)

#执行结果
<__main__.ObjectCreator object at 0x0497B330>

但在Python中class还有更深的用意,即Class同样也是对象。

class ObjectCreator(object):
    pass

当你使用关键字 class 时,Python执行后会创建一个OBJECT,即执行上述代码会在内存中创建“ObjectCreator”对象。

这个对象(class)本省就能创造实例(my_object)这就是为什么它是类。
但同时他也是一个对象,你可以用来:\
1.你可以把它分配给一个变量\
2.可以复制\
3.可以给它添加属性\
4.可以把它作为一个函数参数传递

print(ObjectCreator)#可以打印,因为他是一个对象


def echo(o):
    print(o)

echo(ObjectCreator)#可作为参数传递



print(hasattr(ObjectCreator, 'new_attribute'))


ObjectCreator.new_attribute = 'foo' #增加属性

print(hasattr(ObjectCreator, 'new_attribute'))

print(ObjectCreator.new_attribute)

ObjectCreatorMirror = ObjectCreator #赋值给变量

print(ObjectCreatorMirror.new_attribute)

print(ObjectCreatorMirror())

下边是以上的输出

<class '__main__.ObjectCreator'>
False
True
foo
foo
<__main__.ObjectCreator object at 0x04DF22B0>

动态的创建class

可以在方法中动态的创建类

见以下代码:

>>> def choose_class(name):
...     if name == 'foo':
...         class Foo(object):
...             pass
...         return Foo # return the class, not an instance
...     else:
...         class Bar(object):
...             pass
...         return Bar
...
>>> MyClass = choose_class('foo')
>>> print(MyClass) # the function returns a class, not an instance
<class '__main__.Foo'>
>>> print(MyClass()) # you can create an object from this class
<__main__.Foo object at 0x89c6d4c>

但以上也不是很动态,因为依然要自己写整个类。思考一下,既然class是一个object,根据面向对象思想,他肯定是由什么东西创建的。当时用class关键字的时候,Python自动的创建了一个对象(之前说过),但是和Python中众多事情一样(暂时还不知道什么事),它可以手动创建。

我们来使用 type 函数观察一下object的类型。

>>> print(type(1))
<type 'int'>
>>> print(type("1"))
<type 'str'>
>>> print(type(ObjectCreator))
<type 'type'>
>>> print(type(ObjectCreator()))
<class '__main__.ObjectCreator'>

Amazing!我们看到 type 有完全不同的能力,它也可以动态地创建类。type 可以将类的描述作为参数,并返回一个类。让我们接着看type是怎么工作的:

type(name of the class,
     tuple of the parent class (for inheritance, can be empty),
     dictionary containing attributes names and values)

eg:

>>> class MyShinyClass(object):
...       pass

可以手动被创建:

>>> MyShinyClass = type('MyShinyClass', (), {}) # returns a class object
>>> print(MyShinyClass)
<class '__main__.MyShinyClass'>
>>> print(MyShinyClass()) # create an instance with the class
<__main__.MyShinyClass object at 0x8997cec>

type 接受一个字典来定义类的属性:

>>> class Foo(object):
...       bar = True#自动创建
>>> Foo = type('Foo', (), {'bar':True})


>>> print(Foo)
<class '__main__.Foo'>
>>> print(Foo.bar)
True
>>> f = Foo()
>>> print(f)
<__main__.Foo object at 0x8a9b84c>
>>> print(f.bar)
True

当然也可以内敛与type中:

>>>   class FooChild(Foo):
...         pass

>>> FooChild = type('FooChild', (Foo,), {})
>>> print(FooChild)
<class '__main__.FooChild'>
>>> print(FooChild.bar) # bar is inherited from Foo
True

可以利用此特性向类中添加方法:

>>> def echo_bar(self):
...       print(self.bar)
...
>>> FooChild = type('FooChild', (Foo,), {'echo_bar': echo_bar})
>>> hasattr(Foo, 'echo_bar')
False
>>> hasattr(FooChild, 'echo_bar')
True
>>> my_foo = FooChild()
>>> my_foo.echo_bar()
True

这是Python利用关键字 class 能做的事,这些都是通过 ==metaclass== 实现的。

接下来让我们来看看什么是metaclass?

敲黑板!! 元类(metaclass)就是Python用来创造类的类

通过上边的学习我们知道Python中的class也是对象。\
而这些class就是metaclass创建的,class是metaclass的对象。
可以表示如下:

MyClass = MetaClass()
my_object = MyClass()

也可以表示如下:

MyClass = type('MyClass', (), {})

这是因为方法 type 实际上是一个元类,是Python用来在幕后创建所有类的。

有一点,之所以使用 type 而没用 Type 是因为这是一个与str的一致性的问题,这个类创造了字符串对象,并且int类创建了整型对象。type 就是创建类对象的类。
可以使用class 属性检测Python中的一切事物。我们会发现Python一切皆对象:

>>> 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'>

question? 那好奇宝宝要问了classclass是什么呢?

答案是:type

here we are:

>>> age.__class__.__class__
<type 'type'>
>>> name.__class__.__class__
<type 'type'>
>>> foo.__class__.__class__
<type 'type'>
>>> b.__class__.__class__
<type 'type'>

好了,相信到这里你已经明白了metaclass是什么了,如果乐意的话,你可以叫它“类工厂”。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值