怎么选择网站建设公司,在线电子印章制作,design工业设计,免费做国际网站有哪些4.10.2 属性篇
4.10.2.1 getattr、getattribute
通常我们可以通过obj.attr访问某个对象的属性。而__getattr__则是用来处理我们在获取某个不存在的属性时希望的处理。 默认情况下#xff0c;如果我们获取了一个不存在的属性时#xff0c;会报错#xff1a;AttributeError。…4.10.2 属性篇
4.10.2.1 getattr、getattribute
通常我们可以通过obj.attr访问某个对象的属性。而__getattr__则是用来处理我们在获取某个不存在的属性时希望的处理。 默认情况下如果我们获取了一个不存在的属性时会报错AttributeError。
from icecream import icclass A:def __init__(self):self.test tdef __getattr__(self, item):print(fgetting {item})raise AttributeErrora A()
ic(a.test)ic| a.test: ‘t’ 如果存在属性则不会调用__getattr__方法。否则将会调用该方法
from icecream import icclass A:def __init__(self):...def __getattr__(self, item):print(fgetting {item})raise AttributeErrora A()
ic(a.test)Traceback (most recent call last): File “E:\BaiduSyncdisk\FrbPythonFiles\t1.py”, line 14, in ic(a.test) File “E:\BaiduSyncdisk\FrbPythonFiles\t1.py”, line 10, in getattr raise AttributeError AttributeError getting test __getattribute__方法则是只要尝试获取某个属性不管这个属性存在不存在都会调用该方法。
from icecream import icclass A:def __init__(self):self.data abcself.counter 0def __getattribute__(self, name):if name data:self.counter 1return super().__getattribute__(name)o A()
ic(o.data)
ic(o.data)
ic(o.counter)ic| o.data: ‘abc’ ic| o.data: ‘abc’ ic| o.counter: 2 注意 1、在重写__getattr__和__getattribute__方法时很容易造成无限递归的情况因为只要在这2个方法中引用了属性那么又会很容易再次调用这2个方法。 2、当存在着2个方法时调用了某个不存在的属性时只会调用__getattribute__方法而不会调用__getattr__方法。
4.10.2.2 setattr
在类属性赋值的时候会调用魔法方法__setattr__即便是在类的初始化__init__方法中也一样。我们可以通过super().setattr(name, value)调用类的默认属性赋值方法。
from icecream import icclass A:def __init__(self):self.data abcself.counter 0def __setattr__(self, name, value):print(setattr, name, value)super().__setattr__(name, value)o A()
ic(o.data)
o.data ufosetattr data abc setattr counter 0 setattr data ufo 14:16:43| o.data: ‘abc’ 4.10.2.3 delattr
当我们尝试用del关键字删除对象中某个属性时就会调用__delattr__魔法方法。
from icecream import icclass A:def __init__(self):self.data abcself.counter 0def __delattr__(self, name):print(delattr, name)super().__delattr__(name)o A()
del o.data
ic(o.data)delattr data Traceback (most recent call last): File “E:\t1.py”, line 16, in ic(o.data) AttributeError: ‘A’ object has no attribute ‘data’ 4.10.2.4 dir
通常我们可以通过使用dir函数获取到某个对象的内置属性和方法等信息。可以通过修改对象中的__dir__魔法方法进行定制化返回结果。
from icecream import icclass A:def __init__(self):self.data abcdef test(self):...def __dir__(self):return [None]o A()
ic(dir(o))14:28:15| dir(o): [None] 4.10.2.5 get、set、delete
在Python中魔法方法__get__用于定义一个描述符descriptor。描述符是一种带有绑定行为的对象其主要目的是管理类和实例成员的访问。在访问对象的属性时当Python检测到它属于描述符时就会自动调用相应的描述符方法。 下面是一个简单的例子演示了如何使用__get__魔法方法来创建一个简单的计数器描述符
class Counter:def __init__(self):self.value 0def __get__(self, instance, owner):return self.valuedef __set__(self, instance, value):self.value value if value 0 else 0def __delete__(self, instance):print(instance, del)class MyClass:counter Counter()obj MyClass()
print(obj.counter) # 输出 0
obj.counter -1
print(obj.counter) # 输出 0
obj.counter 10
print(obj.counter) # 输出 10
del obj.countermain.MyClass object at 0x000002AEF8BEBDC0 del 在上面的代码中我们使用Counter类创建了一个计数器描述符并将其作为MyClass类的成员变量counter进行使用。当我们尝试读取MyClass实例的counter属性时Python会自动调用Counter类中的__get__方法来返回该计数器的值。当我们尝试设置counter属性时Python会自动调用Counter类中的__set__方法来设置计数器的值。 这个描述符确保计数器不会被负数重置并且永远只会递增。实际上我们的代码中没有对计数器递增做任何操作但是当你在实际应用场景中使用描述符时可能会在__get__和__set__方法中添加更多的逻辑。例如你可以创建一个验证器描述符它将确保属性值满足某些条件。 当删除该描述器时会调用__delete__方法。
4.10.2.6 slots(类属性)
在Python中__slots__是一个类属性class attribute用于限制实例能够动态绑定的属性。它是一个字符串或字符串组成的元组其中包含类允许的属性名称列表。 使用__slots__可以有效地减少实例所占用的内存空间并提高访问实例属性的速度。这是因为它将属性名存储在特殊数组 slots 中而不是在每个实例中创建一个字典来存储属性。 下面是一个简单的例子演示了如何在类中使用__slots__属性
class Person:__slots__ (name, age)def __init__(self, name, age):self.name nameself.age agep Person(John, 30)
print(p.name) # output: John
print(p.age) # output: 30p.email johnexample.com # AttributeError: Person object has no attribute email在这个例子中我们定义了一个Person类并将它的__slots__设置为(‘name’, ‘age’)。这意味着Person类只允许动态绑定name和age属性任何其他属性都会抛出AttributeError异常。通过这种方式我们可以确保Person类中只维护预定义的属性。