注册 登录

清河洛

python中属性操作的魔法方法

qingheluo2018-11-23清河洛416
__getattribute__():属性访问拦截器在访问对象的属性时自动调用。在python中,类的属性和方法都理解为属性,均可以通过__getattribute__访问或拦截。class Test: def __init__(self,x,y): self.x=x self.y=y def __getattribute__(self,name): if name == 'x': return '想要获取x值?没门' else: return super()....

__getattribute__():属性访问拦截器

在访问对象的属性时自动调用。在python中,类的属性和方法都理解为属性,均可以通过__getattribute__访问或拦截。

class Test:
    def __init__(self,x,y):
        self.x=x
        self.y=y
    def __getattribute__(self,name):
        if name == 'x':
            return '想要获取x值?没门'
        else:
            return super().__getattribute__(name)
a=Test(2,5)
print(a.x)
想要获取x值?没门
print(a.y)
5

Test类对父类object类中的__getattribute__()方法进行了重写,参数name对应的是要访问的属性,要访问x属性,对该属性重写,返回与x值不同的字符串,访问y属性时,调用其父类中的__getattribute__()方法,返回正常的y属性的值。

PS:最后else语句使用的是调用父类的__getattribute__()方法返回正常值,而不是直接返回self.name,因为这样会导致无限递归,从而程序崩溃

__getattr__(self, name):访问的name属性不存在的时候自动调用该方法

__setattr__(self, name, value):给属性赋值

def __setattr__(self, name, value):
    self.name = value
    # 每次执行语句self.name = value语句都自动调用self.__setattr__(name, value),导致一直调用自己(无限递归),直到程序崩溃
def __setattr__(self, name, value):
    self.__dict__[name] = value 
    # 使用__dict__进行赋值是以正确的做法

__delattr_(self, name):删除属性,和__setattr__()方法一样,不要使用del self.name语句操作,会无限递归导致程序崩溃,使用del self.__dict__[name]语句操作

@property访问器和@key.setter修改器

class Demo:
    def __init__(self,name :str):
        self._name=name

    @property
    def xingming(self):
        return self._name

    @xingming.setter
    def xingming(self,new_name):
        self._name=new_name

demo = Demo("one")
print(demo.xingming,'--',demo._name)

demo.xingming="two"
print(demo.xingming,'--',demo._name)

demo._name="three"
print(demo.xingming,'--',demo._name)

运行输出:
one -- one
two -- two
three -- three

可以看出,通过装饰器可以隐藏对象中的真实属性,并对属性获取和修改进行一定的拦截



网址导航