python 怎么更好的理解元类
2018-05-11 18:30
246 查看
类即对象
在理解元类之前,需要先掌握Python中的类,Python中类的概念与SmallTalk中类的概念相似。
在大多数语言中,类是用来描述如何创建对象的代码段,这在Python中也是成立的:
>>> class ObjectCreator(object): ... pass ... >>> my_object = ObjectCreator() >>> print(my_object) <__main__.ObjectCreator object at 0x8974f2c>Python中,类其实也是对象。当我们使用关键字class的时候,Python会执行这段代码,然后生成一个对象。下面的代码在内存中创建一个对象
ObjectCreator:
>>> class ObjectCreator(object): ... pass ...当一个对象具有创建对象的能力时,就称该对象为类。
所以类本质上还是一个对象,因此它具有以下属性:
- 可以将它赋值给其它变量
- 可以对它进行复制
- 可以给它添加属性
- 可以将它传递给函数作为参数
例如:
>>> print(ObjectCreator) # you can print a class because it's an object <class '__main__.ObjectCreator'> >>> def echo(o): ... print(o) ... >>> echo(ObjectCreator) # you can pass a class as a parameter <class '__main__.ObjectCreator'> >>> print(hasattr(ObjectCreator, 'new_attribute')) False >>> ObjectCreator.new_attribute = 'foo' # you can add attributes to a class >>> print(hasattr(ObjectCreator, 'new_attribute')) True >>> print(ObjectCreator.new_attribute) foo >>> ObjectCreatorMirror = ObjectCreator # you can assign a class to a variable >>> print(ObjectCreatorMirror.new_attribute) foo >>> print(ObjectCreatorMirror()) <__main__.ObjectCreator object at 0x8997b4c>
动态创建类
既然类就是对象,那我们就可以像创建其他对象一样动态创建类。首先,在函数中使用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关键字的时候,Python会自动创建类,Python也提供了方法让我们手动来创建类。
还记得type()函数吗?这个函数可以获取对象的类型。
>>> print(type(1)) <type 'int'> >>> print(type("1")) <type 'str'> >>> print(type(ObjectCreator)) <type 'type'> >>> print(type(ObjectCreator())) <class '__main__.ObjectCreator'>type还有另外一个功能,那就是创建类。type使用类的相关描述作为参数,然后返回一个类。
type创建类的语法如下:
type(类名,基类元组(可以为空,用于继承), 包含属性或函数的字典)例如:
>>> 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})通过
type创建的类使用方式跟普通类一样:
>>> 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 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而且,我们还可以在动态创建类之后,给类添加更多的方法和属性:
>>> def echo_bar_more(self): ... print('yet another method') ... >>> FooChild.echo_bar_more = echo_bar_more >>> hasattr(FooChild, 'echo_bar_more') True
什么是元类?
通常,我们定义类来创建对象,但是现在我们知道类也是对象。那么是通过什么来创建类呢?答案就是元类。你可以想象关系如下:MyClass = MetaClass() MyObject = MyClass()你已经知道使用
type可以创建类:
MyClass = type('MyClass', (), {})那是因为type函数实际上就是一个元类,Python使用type作为元类来创建所有的类。
通过检查class属性,我们可以知道,其实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'>那么
__class__的
__class__是什么呢?
>>> age.__class__.__class__ <type 'type'> >>> name.__class__.__class__ <type 'type'> >>> foo.__class__.__class__ <type 'type'> >>> b.__class__.__class__ <type 'type'>所以类其实就是通过元类来创建的,你可以将元类称之为类工厂。
type是内置的元类,Python默认使用它来创建类。当然,我们也可以定义属于我们自己的元类。
阅读更多
相关文章推荐
- 深刻理解Python中的元类(metaclass)
- 深入理解Python中的元类(metaclass)
- 深刻理解Python中的元类(metaclass)
- 深刻理解Python中的元类(metaclass)
- python面向对象中的__init__方法怎么理解?
- 深刻理解Python中的元类(metaclass)
- [Python]五分钟理解元类(Metaclasses)
- 深刻理解Python中的元类(metaclass)
- python——深刻理解Python中的元类(metaclass)
- 深刻理解Python中的元类
- 深刻理解Python中的元类(metaclass)
- 深刻理解Python中的元类(metaclass)
- python——深刻理解Python中的元类(metaclass)
- 深刻理解Python中的元类(metaclass)
- 深刻理解Python中的元类-转自伯乐在线
- Python私有方法不能外部调用怎么理解?
- 简单、通俗地理解python中类与元类(metaclass)及运用
- 深刻理解Python中的元类(metaclass)
- python高级编程---->深刻理解Python中的元类(metaclass)
- 深刻理解Python中的元类(metaclass)以及元类实现单例模式