面向对象进阶-元类
一般的通过引入进行创建一个类
from urllib.request import Request # 引入模块之后 动态创建了一个 Request 类
from fake_useragent import UserAgent
r = Request('https://www.baidu.com', headers={
'User-Agent': UserAgent().random
}) # 创建一个 Request类的实例
# <urllib.request.Request object at 0x0000016B24677E80> <class 'urllib.request.Request'>
print(r, type(r)) # 打印 Request类的实例的类型
print(Request, type(Request)) # <class 'urllib.request.Request'> <class 'type'> | 一个类的类型就是 <class 'type'>
使用 type 创建一个类
type 是一个专用于创建类的函数?? 可以查看类型或者变量的 类型
Request 就是一个类 class 数据类型就是 type
r 就是一个实例 类其数据类型就是 class Request
# 静态创建类
"""
class Person(object):
def say(self, s='hello'):
print('我说: %s' % s)
"""
def say(self, s='hello'):
print('我说: %s' % s)
# 动态创建类
Person = type('Person', (object,), dict(say=say))
print(Person, type(Person))
p = Person()
print(p, type(p))
还可以使用 元类来创建一个类
# 元类 metaclass 动态创建类
# 所有的元类必须继承 type
# tm感觉好麻烦!!
class PersonMetaClass(type):
def __new__(mcs, name, bases, dict):
def say(self, s='hello'):
print('我说: %s' % s)
dict['say'] = say
return type.__new__(mcs, name, bases, dict)
class Person(object, metaclass=PersonMetaClass):
pass
print(Person, type(Person))
p = Person()
print(p, type(p))
有趣的规律
type 是所有类的类型
print(int.__class__, a.__class__, a.__class__.__class__)
把类属性全部改为大写
def upperAttr(name, bases, dict):
# 遍历类中的所有的属性 把非私有属性改为大写
newDict = {}
for key, item in dict.items():
if not key.startswith('__'): # 过滤私有的
newDict[key.upper()] = item
return type(name, bases, newDict)
class Emp(object, metaclass=upperAttr):
name = '张三'
age = 18
if __name__ == '__main__':
pass
print(hasattr(Emp, 'name')) # 判断类或对象实例中有这个属性
print(hasattr(Emp, 'name'.upper()))
print(hasattr(Emp, 'age'))
print(hasattr(Emp, 'age'.upper()))