元类
class ObjectCreator(object):
name = "haha"
pass
my_object = ObjectCreator()
print(my_object)
def echo(cls):
print(cls)
print(echo(ObjectCreator))
# 类对象可以实例化实例对象
# 第二种 用type
def print_self(cls):
A = type("A", (), {})
# 参1 是元类的名字, 参2 元组 是 继承于 什么类, 参3 字典 设置 类属性, 类方法,
自定义元类
# 方法1
class Upper_attr(type):
def new(cls, class_name, class_parents, class_attr):
# class_name 类的名字
# class_parents 类所继承的属性
# class_attr 类的属性
# 创建一个新的字典
new_dict = {}
# 遍历 旧的字典, 在新的字典 存放为key为大写的, 键值对
for name, value in class_attr.items():
# 如果不是__开头的属性, 就修改key为大写
if not name.statswith("__"):
new_dict[name.upper()] = value
return type(class_name, class_parents, new_dict)
# 方法2
def upper_attr(class_name, class_parents, class_attr):
# class_name 类的名字
# class_parents 类所继承的属性
# class_attr 类的属性
# 创建一个新的字典
new_dict = {}
# 遍历 旧的字典, 在新的字典 存放为key为大写的, 键值对
for name, value in class_attr.items():
# 如果不是__开头的属性, 就修改key为大写
if not name.statswith("__"):
new_dict[name.upper()] = value
return type(class_name, class_parents, new_dict)
class Foo(object, metaclass=upper_attr):
bar = "bip"
总结
__getattribute__和__getattr__都是对访问属性时的特殊操作
- __getattr__只针对未定义属性的调用
- __getattribute__针对所有的属性运行
描述符
class MyDecriptor:
def __get__(self, instance, owner)
print("get called")
def __set__(self, instance, value):
print("set called")
def __delete__(self, instance):
print("delete called")
class Foo:
attr = MyDescriptor()
设置 复制不为零
class NonNegative:
def __init__(self, num):
self.num = num
def __get__(self, instance, owner):
return self.num
def __set__(self, instance, value):
ifvalue<0:
raise ValueError("数值不能为零")
class Movie:
rating = NonNegative(0)
budget = NonNegative(0)
gross = NonNegative(0)
def __init__(self, title, rating, budget, gross):
self.title = title
self.rating = rating
self.budget = budget
self.gross = gross
movie = Movie("战狼", 10, 100, 1000)
描述符1
class C:
y = 2
def __init__(self, x):
self.x = x
def func(self):
print(self.x)
# def __set__(self, value):
c = C()
# 获取 类 属性
print(type(c).__dict__)
# 获取 实例 属性
print(c.__dict__) # 字典
# 也可以用 vars函数
print(vars(c)) # {'x': 2}
类方法 的描述符
class MyClassmethod:
def __init__(self, func):
self.func = func
def __get__(self, instance, owner):
def call(*args, **kargs):
self.func(owner, *args, **kargs):
return call
class A:
def __init__(self):
self.name = "秀儿"
@myclassmethod
def sum(cls, num)
pirnt("cls ----"num)
a = A()
a.sum()