1. 类也是对象
class Person(object): num = 0 print("---person class") def __init__(self): self.name = "abc" print("hello world") print(Person) ### 结果 ---person class hello world <class '__main__.Person'>
2. 动态地创建类
>>> def choose_class(name): … if name == 'foo': … class Foo(object): … pass … return Foo # 返回的是类,不是类的实例 … else: … class Bar(object): … pass … return Bar … >>> MyClass = choose_class('foo') >>> print MyClass # 函数返回的是类,不是类的实例 <class '__main__'.Foo> >>> print MyClass() # 你可以通过这个类创建类实例,也就是对象 <__main__.Foo object at 0x89c6d4c>
但这还不够动态,因为你仍然需要自己编写整个类的代码。由于类也是对象,所以它们必须是通过什么东西来生成的才对。当你使用class关键字时,Python解释器自动创建这个对象
3. 使用type创建类
type还有一种完全不同的功能,动态的创建类。
type可以接受一个类的描述作为参数,然后返回一个类。(要知道,根据传入参数的不同,同一个函数拥有两种完全不同的用法是一件很傻的事情,但这在Python中是为了保持向后兼容性)
type可以像这样工作:
type(类名, 由父类名称组成的元组(针对继承的情况,可以为空),包含属性的字典(名称和值))
#### class Test In [1]: class Test: ...: pass ...: In [2]: t1 = Test() ### type 创建Test2类 In [3]: Test2 = type("Test2",(),{}) #type(类名, 父类(元组),属性(字典) In [4]: t2 = Test2() In [5]: type(t1) Out[5]: __main__.Test In [6]: type(t2) Out[6]: __main__.Test2
实例对象是class对象创建的,class是type创建的,type就是元类
最元始创建类的东西,就是元类
1)创建带属性的类
In [7]: Person2 = type("Person2",(),{"num":0}) #带有属性的 In [8]: p2 = Person2() In [9]: p2.num Out[9]: 0
2)带有方法的类
In [10]: def printNum(self): ....: print("---num -- %d"%self.num) ....: In [11]: Test3 = type("Test3",(),{"printNum":printNum}) In [12]: t3 = Test3() In [15]: t3.num = 100 In [16]: t3.printNum() ---num -- 100
### 等价的 In [17]: class printNum2: ....: def printNum(self): ....: print("---num-%d"%self.num) ....: In [18]: t2 = printNum2() In [19]: t2.num = 100 In [20]: t2.printNum() ---num-100
3)带有继承的类
In [21]: class Animal(object): ....: def eat(self): ....: print('---eat--') ## 创建个狗类 In [23]: class Dog(Animal): ....: pass In [25]: wangcai = Dog() In [26]: wangcai.eat() ---eat-- ##创建个猫类 In [27]: Cat = type("Cat",(Animal,),{}) In [28]: tom = Cat() In [29]: tom.eat() ---eat--
4. 到底什么是元类(终于到主题了)type
元类就是用来创建类的“东西”。你创建类就是为了创建类的实例对象,不是吗?但是我们已经学习到了Python中的类也是对象。
元类就是用来创建这些类(对象)的,元类就是类的类,你可以这样理解为:
Python中所有的东西,注意,我是指所有的东西——都是对象。这包括整数、字符串、函数以及类。它们全部都是对象,而且它们都是从一个类创建而来,这个类就是type。
#type就是Python在背后用来创建所有类的元类 #你可以通过检查__class__属性来看到这一点 In [31]: wangcai.__class__ Out[31]: __main__.Dog In [32]: tom.__class__ Out[32]: __main__.Cat In [33]: Cat.__class__ Out[33]: type In [30]: Dog.__class__ Out[30]: type In [34]: type.__class__ Out[34]: type
5. 自定义元类
python2中 __metaclass__ = upper_attr
#-*- coding:utf-8 -*- def upper_attr(future_class_name, future_class_parents, future_class_attr): #遍历属性字典,把不是__开头的属性名字变为大写 newAttr = {} for name,value in future_class_attr.items(): if not name.startswith("__"): newAttr[name.upper()] = value #调用type来创建一个类 return type(future_class_name, future_class_parents, newAttr) class Foo(object): __metaclass__ = upper_attr #设置Foo类的元类为upper_attr bar = 'bip' print(hasattr(Foo, 'bar')) print(hasattr(Foo, 'BAR')) f = Foo() print(f.BAR)
python3中 class Foo(object, metaclass=upper_attr):
#-*- coding:utf-8 -*- def upper_attr(future_class_name, future_class_parents, future_class_attr): #遍历属性字典,把不是__开头的属性名字变为大写 newAttr = {} for name,value in future_class_attr.items(): if not name.startswith("__"): newAttr[name.upper()] = value #调用type来创建一个类 return type(future_class_name, future_class_parents, newAttr) class Foo(object, metaclass=upper_attr): bar = 'bip' print(hasattr(Foo, 'bar')) print(hasattr(Foo, 'BAR')) f = Foo() print(f.BAR)