__set__,__setattr__,__getattr__等
2020-03-06 本文已影响0人
洛克黄瓜
__get__,__set__,__delete__
设计描述符descriptor需要使用
# A descriptor
class String:
def __init__(self, name):
self.name = name
def __get__(self, instance, cls):
if instance is None:
return self
return instance.__dict__[self.name]
def __set__(self, instance, value):
if not isinstance(value, str):
raise TypeError('Expected a string')
instance.__dict__[self.name] = value
# A class with a descriptor
class Person:
name = String('name')
def __init__(self, name):
self.name = name
# Extending a descriptor with a property
class SubPerson(Person):
"""这个子类把属性的三个方法都重写了
"""
@property
def name(self):
print('Getting name')
return super().name
@name.setter
def name(self, value):
print('Setting name to ', value)
super(SubPerson, SubPerson).name.__set__(self, value) # __set__是属性的方法
@name.deleter
def name(self):
print('Deleting name')
super(SubPerson, SubPerson).name__delete__(self)
__getattr__, __getattribute__,getattr
- __getattr__
获取对象属性时使用,当找不到属性时就会调用这个方法,我们可以重写这个方法来实现一些特殊功能,比如给个默认值啥的 - __getattribute__
获取对象属性使用,这个是任何情况下都会隐式调用的方法。实际上这个方法会在 __getattr__之前调用 - getattr
内置函数,getattr(object, name, default=None)
setattr, __setattr__
- setattr
内置函数,setattr(object, name, default=None) - __setattr__
给对象赋予属性值时使用
__getitem__, __setitem__
给对象进行容器化可以对类实现这个函数
class A:
def __setitem__(self, key, value):
setattr(self, key, value)
def __getitem__(self, key):
return getattr(self, key)
a = A()
a.x = 3
print(a["x"])
----
output:3
如上,可见,通过容器化,使得获取对象的属性有点像访问dict或是list这样的容器