元类
1. 如何创建类
class Myobject(object):
pass
2. 动态的创建类
def Choose_Class(name):
if name=='fish':
class Fish(object):
pass
return Fish #返回的是类, 不是类的实例
else:
class Crab(object):
pass
return Crab
Myclass=Choose_Class("fish")
print(Myclass) #函数返回的是类, 不是类的实例
print(Myclass())
执行结果:
但这还不够动态, 因为你仍然需要⾃⼰编写整个类的代码。 由于类也是对象, 所以它们必须是通过什么东⻄来⽣成的才对。 当你使⽤class关键字时,
python解释器自动创建这个对象,但就像paython中大多数的事情一样,python仍然给你提供手动处理的方法
还记得内建函数type么, 这个古老但强大的函数能够让我们知道一个对象的类型是什么, 就像这样:
咦,为什么Myobject类的类型 是type呢,我们接着往下看看
3. 使⽤type创建类
type还有⼀种完全不同的功能, 动态的创建类。
type(类名, 由⽗类名称组成的元组(针对继承的情况, 可以为空) , 包含属性的字典(名称和值) )
⽐如下⾯的代码:
@staticmethod def TestStaticMethod(): print("static method……") @classmethod def TestClassmethod(cls): print("class method……") def echo_bar(self): print(self.bar) Animal=type('Animal',(),{'bar':True}) Fish=type('Fish',(Animal,),{"echo_bar":echo_bar,'TestStaticMethod':TestStaticMethod,"TestClassmethod":TestClassmethod}) fish=Fish()
可以看到, 在Python中, 类也是对象, 你可以动态的创建类。 这就是当我们使⽤关键字class时Python在幕后做的事情, ⽽这就是通过元类来实现的。
4. 到底什么是元类(终于到主题了)
元类就是⽤来创建类的“东⻄”。 你创建类就是为了创建类的实例对象, 不是吗?
但是我们已经学习到了Python中的类也是对象。元类就是⽤来创建这些类(对象) 的, 元类就是类的类, 你可以这样理解为 :
MyClass = MetaClass() #使⽤元类创建出⼀个对象, 这个对象称为“类” MyObject = MyClass() #使⽤“类”来创建出实例对象
我们已经看到了type可以让你像这样做:
MyClass = type('MyClass', (), {})
这是因为函数type实际上是⼀个元类。 type就是Python在背后⽤来创建所有类的元类
Python中所有的东⻄, 注意, 我是指所有的东⻄——都是对象。 这包括整数、 字符串、 函数以及类。 它们全部都是对象,⽽且它们都是从⼀个类创建⽽来, 这个类就是type。
type就是创建类对象的类。 我们可以通过检查__class__属性去看看, 然后我们看看任何一个.__class__的.__class__属性又能得到什么呢
因此,元类是一种可以创建类对象的东西, type就是python内建的元类。
__metaclass__属性
可以在定义⼀个类的时候为其添加__metaclass__属性。
class Fish(object): __meta__=something
如果这么做勒, python会使用原来来创建Fish, 但是,这里面有一些步骤哦,首先写下 class Fish(object), 但是Fish 是还没有在内存中创建的, python 会在类的定义中寻找__metaclass__ 属性,
如果找到了,python 机会利用它来创建类Fish , 如果没有找到, 就会利用内建的type来创建这个类
当我们写下如下代码的时候:
class Fish(animal): __meta__=something
python做了如下操作:
1. Fish 中又__metaclass__么 如果有,那么python会通过__metaclass__ 创建一个名字为Fish的类
2.如果python中没有找到__metaclass__ 那么会继续在父类animal 中寻找这个属性,并尝试和前面相同的操作
3.如果父类中也找不到__metaclass__ 那么就会在模块层次中寻找__metaclass__ 并尝试做之前相同的操作
现在的问题是: 我们可以在__metaclass__ 中放置一些什么代码呢
答案: 创建一个类的东西,那么用什么可以来创建一个类呢 type 或者子类化type的东东呀
使用函数当作元类:
def UpAttr(future_class_name,future_class_parents,future_class_attr): result={} for name,value in future_class_attr.items(): if not name.startswith("__"): result[name.upper()]=value return type(future_class_name,future_class_parents,result) #python3的写法 class Fish(object,metaclass=UpAttr): bar='hhhh' #python2的写法 class Fish(object): __metaclass__=UpAttr bar='hhhh' print(hasattr(Fish,'bar')) print(hasattr(Fish,'BAR'))
使用class 作为元类:
class UpperAttrMetaClass(type): def __new__(cls,future_class_name,future_class_parents,future_class_attr): result={} for name,value in future_class_attr.items(): if not name.startswith("__"): result[name.upper()]=value return type(future_class_name,future_class_parents,result) #python3的写法 class Fish(object,metaclass=UpperAttrMetaClass): bar='hhhh' print(hasattr(Fish,'bar')) print(hasattr(Fish,'BAR'))