在python type中,可以使用type
来动态创建类,和使用class
本质是一致的。
class X:
a = 1
X = type('X', (object,), dict(a=1))
除了使用type方法
来创建类,我们还可以使用metacalss=type
来自定义类的创建,当我们在定义类的时候,默认省略了metaclass=type
class Person(object,metaclass=type):
def __init__(self, age):
self.age = 1
当Person
类使用metaclass=type
时,本质就是使用了Person = type('Person', (object,), dict(age=1))
。那么我们就可以通过继承type
类并重新实现其__new__
方法来实现创建类的个性化操作。
class New_type(type):
# 因为继承type,所以第一个参数是类的名称,第二个是基类,第三个是属性
def __new__(cls, clsname, bases, attrs):
# 在这里添加一些对clsname,bases,和attrs的操作
new_clsname = clsname
new_bases = bases
new_attrs = attrs
return type(new_clsname, new_bases, new_attrs)
# return type.__new__(cls, new_clsname, new_bases, new_attrs) # 更oop的写法
# return super().__new__(cls, new_clsname, new_bases, new_attrs) # 最oop的写法
class Foo(metaclass=New_type):
bar = 'bip'
具体应用可以看python metaclass应用
辅助教程
我们使用class
创建object
,那class
本质又是object
那class
是谁创建的呢,答案是metaclass
metaclass
就是class
的class
python所有东西都是对象,由不同的类来创建,如下代码:
age = 35
age.__class__ # <type 'int'> 是int类
name = 'bob'
name.__class__ # <type 'str'> 是str类
def foo(): pass
foo.__class__ # <type 'function'> 是function类
class Bar(object): pass
b = Bar()
b.__class__ # <class '__main__.Bar'> 是class类
那么创建这些对象的类的类是谁呢,既__class__
的__class__
是谁呢,答案是type
注意这里type
是小写,(一般类都是大写Type,估计这是为了和type()
方法统一)
a.__class__.__class__ # <type 'type'>
age.__class__.__class__ # <type 'type'>
foo.__class__.__class__ # <type 'type'>
b.__class__.__class__ # <type 'type'>
class Foo(object, metaclass=something):
注意:之前python2中使用__metaclass__
属性,已经废弃了
创建类的过程中,python
做了以下的工作:
1.通过Foo
类的metaclass
创建一个Foo
类对象.如果在Foo
中没有找到metaclass
则会在父类中寻找,如果在父类中还是找不到,则会在模块中寻找metaclass
.如果最终还是找不到,则会使用type
作为metaclass
.既是说默认metaclass=type
可以以继承的方式重写type
来改写类的创建方式
class Foo(metaclass=type):
pass
class MyType(type):
def __init__(self,*args,**kwargs):
print('init')
super(MyType,self).__init__(*args,**kwargs)
def __call__(self, *args, **kwargs):
print('call本质:调用类的__new__,再调用类的__init__')
return super(MyType,self).__call__( *args, **kwargs)
class Foo(metaclass=MyType):
pass
class Bar(Foo):
pass
obj = Bar()
例子
利用metaclass
使得创建类时,将属性都大写:
记住type
(metaclass
)也是一个class
,所以我们可以继承他
class UpperAttrMetaclass(type):
def __new__(cls, name, bases, dct):
attrs = ((name, value) for name, value in dct.items() if not name.startswith('__'))
uppercase_attr = dict((name.upper(), value) for name, value in attrs)
return super(UpperAttrMetaclass, cls).__new__(cls, name, bases, uppercase_attr)
参考:
https://www.cnblogs.com/Simon-xm/p/4034416.html
class Meta(type):
pass
class MyClass(metaclass=Meta):
pass
class MySubclass(MyClass):
pass
https://docs.python.org/3/reference/datamodel.html?highlight=metaclass#metaclasses
https://www.cnblogs.com/Simon-xm/p/4034416.html
https://zhuanlan.zhihu.com/p/98440398
https://stackoverflow.com/questions/100003/what-are-metaclasses-in-python/6581949#6581949
https://blog.csdn.net/jiguanglong/article/details/93204314
https://blog.csdn.net/wwx890208/article/details/80644400
object(class)是具有创建其他object(instance)的能力的