python类属性,类方法的学习
一、__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'