一、使用type创建类
type可以接受一个类的描述作为参数,然后返回一个类。如下:
Test = type('Test',(),{}) print(Test) help(Test)
结果:
<class '__main__.Test'> Help on class Test in module __main__: class Test(builtins.object) | Data descriptors defined here: | | __dict__ | dictionary for instance variables (if defined) | | __weakref__ | list of weak references to the object (if defined)
二、使用type创建带有属性的类
type接受一个字典来为类定义属性,如下:
Dog = type('Dog',(),{'name':'二哈','age':1}) print(Dog) help(Dog)
结果:
<class '__main__.Dog'> Help on class Dog in module __main__: class Dog(builtins.object) | Data descriptors defined here: | | __dict__ | dictionary for instance variables (if defined) | | __weakref__ | list of weak references to the object (if defined) | | ---------------------------------------------------------------------- | Data and other attributes defined here: | | age = 1 | | name = '二哈'
三、使用type实现类的继承
Dog = type('Dog',(),{'name':'二哈','age':1}) print(Dog) help(Dog) DogChild = type('DogChild', (Dog,),{}) print(DogChild) print(DogChild.name)
结果:
<class '__main__.Dog'> <class '__main__.DogChild'> 二哈
四、使用type创建带有方法的类
#普通方法 def test(self): print("test") #静态方法 @staticmethod def static_test(): print("static_test") #类方法 @classmethod def class_test(cls): print("class_test") Test = type('Test',(),{'name':'name','test':test,'static_test':static_test,'class_test':class_test}) print(Test) test = Test() test.test() test.static_test() test.class_test()
结果:
<class '__main__.Test'> test static_test class_test
五、元类
元类的主要目的就是为了当创建类时能够自动地改变类。通常,你会为API做这样的事情,你希望可以创建符合当前上下文的类。
假想一个很傻的例子,你决定在你的模块里所有的类的属性都应该是大写形式。有好几种方法可以办到,但其中一种就是通过在模块级别设定__metaclass__。采用这种方法,这个模块中的所有类都会通过这个元类来创建,我们只需要告诉元类把所有的属性都改成大写形式就万事大吉了。
幸运的是,__metaclass__实际上可以被任意调用,它并不需要是一个正式的类。所以,我们这里就先以一个简单的函数作为例子开始。
class UpperAttrMetaClass(type): # __new__ 是在__init__之前被调用的特殊方法 # __new__是用来创建对象并返回之的方法 # 而__init__只是用来将传入的参数初始化给对象 # 你很少用到__new__,除非你希望能够控制对象的创建 # 这里,创建的对象是类,我们希望能够自定义它,所以我们这里改写__new__ # 如果你希望的话,你也可以在__init__中做些事情 # 还有一些高级的用法会涉及到改写__call__特殊方法,但是我们这里不用 def __new__(cls, 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 # 方法1:通过'type'来做类对象的创建 # return type(future_class_name, future_class_parents, newAttr) # 方法2:复用type.__new__方法 # 这就是基本的OOP编程,没什么魔法 # return type.__new__(cls, future_class_name, future_class_parents, newAttr) # 方法3:使用super方法 return super(UpperAttrMetaClass, cls).__new__(cls, future_class_name, future_class_parents, newAttr) #python2的用法 #class Foo(object): # __metaclass__ = UpperAttrMetaClass # bar = 'bip' # python3的用法 class Foo(object, metaclass = UpperAttrMetaClass): bar = 'bip' print(hasattr(Foo, 'bar')) # 输出: False print(hasattr(Foo, 'BAR')) # 输出:True f = Foo() print(f.BAR) # 输出:'bip'就是这样,除此之外,关于元类真的没有别的可说的了。但就元类本身而言,它们其实是很简单的:
- 拦截类的创建
- 修改类
- 返回修改之后的类