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