前情提要
getattr,gettrubte,setattr,delattr方法的触发时机
obj.getattr 方法,
如果被访问(查找)的属性不存在的时候会触发
obj.gettrbute方法,
访问 查找属性时,第一时间出发该方法
obj.setattr方法
设置属性时,出发该方法
obj.delattr
删除属性的时候会触发
元类
旧式类py27,默认继承intance,
新式类 py3 默认继承object
类型 Type 和类 class
# type的类型是什么,也是type
什么是元类
python中任何新式类以及py3中的任何类都是type元类的一个实例
函数type实际上是一个元类,type就是python在背后用来创建所有类的元类。
注意区分元类和继承的基类
type是元类,所有的类都是通过type创建出来的
元类也可以进行自定义
通过type元类创建类需要三个参数
- 类名 —-str 这个是真正的类名
- 继承的父类,—tup元祖类型,只有一个父类的时候参照上面的写法,可传可不穿,不穿默认继承object
方法和属性 — 类属性,键值对表示属性或者对应的方法
# 定义一个方法
def dunc(self):
print("这是一个self方法")
# 元祖中只有一个元素的写法 (object,)
T = type('Test', (object,), {"attr": 100,'function1':func})
# 返回的是一个类,T是引用名,并非真正的类名,真正的类名为Test
详解:
使用type动态定义类
内置type()函数在传递了一个参数时会返回一个对象类型,对于新式类,通常与对象的class属性相同。type(name,bases,dict) 调用type
type(name,bases,dict) 调用type
name 指定类名称,成为该类的name属性
bases 指定继承类的基类元祖,将成为该类的bases属性
dict 指包含类主体定义的名称空间字典,将成为该类的dict属性自定义元类
自定义元类必须继承type,否则将没有创建类的能力。
type创建类,三个参数,下面看实例# type 创建类 : 三个参数
class MyMetaClass(type):
# 自定义的元类,将类的所有属性名都变成大写
def __new__(cls,name,bases,attr_dict,*args, **kwargs):
print('最基础的自定义元类')
# 遍历属性名称
for k,v in list(attr_dict.items()):
attr_dict[k.upper()] = v
attr_dict.pop(k)
return super().__new__(cls,name,bases,attr_dict)
# 使用super()的调用方式需要传入cls
# 类创建成功,后面如何根据自定义的元类来创建类
class Test(metaclass=MyMetaClass):
# metaclass 用来指定元类,不传默认是type
name ='adi'
age = 99
gender = "男"
print(type(Test)) # <class '__main__.MyMetaClass'>
# print(Test.name)
通过metaclass = 自定义元类名来进行指定,
父类指定元类,子类可以继承父类所指定的元类class MyClass(Test):
pass
print(type(MyClass)) # <class '__main__.MyMetaClass'>
# 自定义元类是可以被继承的