python类属性,类方法学习(__getattr__和__getattribute__等魔法方法)
一、__getattr__和__getattribute__的区别
getattr(self, item)定义当用户试图获取一个不存在的属性的行为
getattribute(self, item)定义该类的属性被访问时的行为
因为,计算机肯定先访问存在的属性,如果没有,再访问不存在的属性,即先访问getattribute(self, item),再访问getattr(self, item)
1、demo01
class Demo: def __getattr__(self, item): return "该属性不存在" demo=Demo() print (demo.x)
## 该属性不存在
2、demo0
class C: def __getattr__(self, name): print(1) def __getattribute__(self, name): print(2) def __setattr__(self, name, value): print(3) def __delattr__(self, name): print(4) c = C() c.x = 1 # 位置一,请问这里会显示什么? print(c.x) # 位置二,请问这里会显示什么?
位置一会显示3,因为c.x=1是赋值操作,所以会访问setattr()魔法方法:位置二显示2和None,因为x是属于实例对象c的属性,所以c.x是访问一个存在的属性,因为会访问getattribute()魔法方法,但我们重写了这个方法,使得它不能按正常的逻辑返回属性值,而是打印一个2代替,由于我们没有写返回值,所以紧接着返回None,并被print()打印出来
3、demo03
class C: def __getattr__(self, name): print(1) return super().__getattr__(name) def __getattribute__(self, name): print(2) return super().__getattribute__(name) def __setattr__(self, name, value): print(3) super().__setattr__(name, value) def __delattr__(self, name): print(4) super().__delattr__(name) c = C() c.x
# 输出以下内容
Traceback (most recent call last): 2 File "E:/Python Program/test.py", line 128, in <module> 1 c.x File "E:/Python Program/test.py", line 113, in __getattr__ return super().__getattr__(name) AttributeError: 'super' object has no attribute '__getattr__'
首先c.x会先调用getattribute()魔法方法,打印2;然后调用super().getattribute(),找不到属性名x,因此会紧接着调用getattr()魔法方法,于是打印1,然后调用super().getattr()。但是Python会告诉你AttrError,super对象木有getattr()
二、动态设置,获取对象属性
""" ------获取对象的信息---- * 判断对象的类型可以用type() * 如果对象是继承关系的可以用isinstance() * isinstance(对象,父类) 返回的是True 或者False * 能用 type()判断的基本类型也可以用 isinstance()判断: 如果要获取一个对象的属性和方法,可以用dir(), 它返回 一个包含字符串的 list """
class Myobj(object): def __init__(self): self.x = 9 def power(self): return self.x * self.x # 定义对象 obj = Myobj() # 测试对象属性的获取 hasattr(obj, "x") # 对象里有属性"x"吗 返回True False print(obj.x) hasattr(obj, "y") # 有属性"y"吗 setattr(obj, "y", 19) # 设置一个属性"y" print(obj.y) print(hasattr(obj, "__init__")) getattr(obj, "y") # 获取属性"y" # 如果获取不存在的属性,会抛出AttributeError # getattr() 还可以传入一个default参数,当获取的属性不存在时,则返回默认值 getattr(obj, "x", 404)
三、给实例对象绑定方法
class Student(object): pass s = Student() # 给对象添加属性 s.name = "Mical" print(s.name) # 定义外部函数 def set_age(self, age): self.age = age # 给实例对象绑定方法 from types import MethodType s.set_age = Method(set_age, s) s.set_age(25) print(s.age) '需要注意的是,给实例对象绑定的方法,对于其他实例是无效的' '要给所有对象使用外部设定的方法,绑定的就是类' def set_score(self, score): self.score = score Student.set_score = MethodType(set_score, Student) # 动态语言能够实现动态绑定,允许我们在程序运行的过程中加功能,
""" __slots__方法可以限制对象仅有的属性 该方法仅对当前类实例起作用,对继承的子类不起作用, 除非子类也定义了,子类实例允许定义的属性就是本身的还有父类的__slots__ """
class Dog(object): __slots__ = ("name", "age") # 用tuple定义允许绑定的属性名称 def get(self): print(self.name) d = Dog() d.name = "Michale" d.get() Michale d.age = 25 d.job = "python"
--------------------------------------------------------------------------- AttributeError Traceback (most recent call last) <ipython-input-10-c0fc7f775871> in <module>() ----> 1 d.job = "python" AttributeError: 'Dog' object has no attribute 'job'

参考:
廖雪峰老师官网:www.liaoxuefeng.com
https://blog.csdn.net/chaowanghn/article/details/54455949

浙公网安备 33010602011771号