Python3 元類編程

在Python中一切接對象,類也是一個對象,所有的類都是有type類創建,我們實際開發中最常用的type方法,是用來獲取某個對象的類型的,例如type(1) ⇒ int 、type(‘str’) ⇒ str。但是type還有一種用法,就是用來創建類的。

1、通過type動態創建無父類、無屬性的類
People = type('People', (), {})

p = People()
print(p)
2、通過type動態創建有父類、無屬性的類
class Animal(object):
    name = '動物類'
    public = '類變量'
    def __init__(self, name):
        self.name = name
Dog = type('Dog', (Animal, ), {})

d = Dog('哈士奇')
print(d)
print(Dog.__bases__)
print(Dog.__mro__)
print(d.name)
print(d.public)
3、通過type動態創建有父類、有屬性的類
class Animal(object):
    name = '動物類'
    public = '類變量'
    def __init__(self, name):
        self.name = name

Dog = type('Dog', (Animal, ), {'age': 2}) # 新增一個age屬性
d = Dog('哈士奇')
print(d)
print(Dog.__bases__)
print(Dog.__mro__)
print(d.name)
print(d.public)
print(d.age)

值得注意的是:在類中方法也是一種屬性,只不過該屬性的值是函數地址而已,因此使用type創建類時,我們也可以創建類的一些方法。
例如:

# 通過type動態創建有類,添加類方法、靜態方法、實例方法
@classmethod
def eat(cls):
    print('類方法')

@staticmethod
def say():
    print('靜態方法')

def get_age(self):
    print('今年%d歲了' % self.age)


People = type('People', (), {'age': 2, 'eat': eat, 'say': say, 'get_age': get_age})
p = People()
People.eat()
p.eat()
p.say()
People.say()
p.get_age()
4、在編寫類時,更改元類,使用自建的元類來創建類

__metaclass__屬性,Python會在類的定義中尋找__metaclass__屬性,如果找到了,Python就會用它來創建類,如果沒有找到,就會用內建的type來創建這個類

def upper_attr(cls, bases, attrs):
    '''
    自定義元類,將所有的共有屬性名都變成大寫的屬性名
    '''
    newAttr = {}
    for key, val in attrs.items():
        if not key.startswith('__'):
            newAttr[key.upper()] = val

    return type(cls, bases, newAttr)


class People(object, metaclass=upper_attr):
    name = 'asd'
    age = 18


p = People()
print(p.NAME) # p.name 會報屬性找不到
print(p.AGE)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章