python面向对象进阶-元类和metaclass

元类

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中, 类也是对象, 你可以动态的创建类。 这就是当我们使⽤关键字classPython在幕后做的事情, ⽽这就是通过元类来实现的。 

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'))








 

 







猜你喜欢

转载自www.cnblogs.com/soaeon/p/8991359.html