16. 属性之增删改查
attribute 属性
1. hasattr(object,name)
用于判断指定的对象object是否有参数name指定的属性或方法
>>> class MyClass(object):
>>> def __init__(self):
>>> self.x = 1
>>> def do_sth(self):
>>> print("do_sth被调用")
>>> mc = MyClass()
>>>
>>> print(hasattr(mc,'x'))
True
>>> print(hasattr(mc,'y'))
False
2. getattr(object,name[, default] ) == object.name
用于获取指定对象object中名为name的属性或方法
>>> print(getattr(mc,'x'))
1
>>> print(getattr(mc,'y'))
AttributeError Traceback (most recent call last)
<ipython-input-14-4d6ba253c0e7> in <module>()
11
---> 12 print(getattr(mc,'y'))
13
AttributeError: 'MyClass' object has no attribute 'y'
>>> print(getattr(mc,'y','查找的属性或方法不存在'))
查找的属性或方法不存在
注:
- 如果不指定参数default,那么当object中不存在name的属性或方法时,抛出AttributeError
- 如果指定了参数default,那么当object中不存在name的属性或方法时,返回default
- 只有在不知道对象信息的情况下,才会去获取对象的信息,如果可以尽量用object.name而不用gettattr()
3. setattr(object,name,value) == object.name = value
用于在指定对象object中添加或修改名为参数name的属性或方法,添加或修改后的值为value
>>> setattr(mc, 'z', 3)
>>> print(getattr(mc, 'z'))
3
4. delattr(object,name) == del object.name
用于删除指定对象object中名为name的属性或方法
>>> delattr(mc, 'z')
>>> print(hasattr(mc,'z'))
False
17. 算术运算符重载
标准算数运算符在默认情况下不能用于自定义类对象的实例对象
>>> class MyClass1(object):
>>> pass
>>> class MyClass2(object):
>>> pass
>>> obj1 = MyClass1()
>>> obj2 = MyClass2()
>>> print(obj1 + obj2) #报错
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-28-00f324e412dc> in <module>()
6 obj2 = MyClass2()
7
----> 8 print(obj1 + obj2)
TypeError: unsupported operand type(s) for +: 'MyClass1' and 'MyClass2'
如果想让标准算数运算符可以用于自定义类对象的实例对象,必须在自定义类对象中实现标准运算符对应的特殊方法:
- 加:__ add__()与__radd__() 在运算符的右边出现需要有__radd__
- 减:__ sub__()与__rsub__()
- 乘:__ mul__()与__rmul__()
- 除:__ truediv__()与__rtruediv__()
- 整除: __ floordiv__()与__rfloordiv__()
先看符号左边是否有__add__,如果有则用__add__的方法,如果没有或返回NotImplemented 则看符号右边是否有__radd__,如果有则用__radd__方法,如果没有就报错TypeError
>>> class MyClass1(object):
>>> def __add__(self, other):
>>> return("这是__add__+的结果")
>>> class MyClass2(object):
>>> def __radd__(self, other):
>>> return("这是__radd__+的结果")
>>> obj1 = MyClass1()
>>> obj2 = MyClass2()
>>> print(obj1 + obj2)
这是__add__+的结果
>>> class MyClass1(object):
>>> pass
>>> class MyClass2(object):
>>> def __radd__(self, other):
>>> return("这是__radd__+的结果")
>>> obj1 = MyClass1()
>>> obj2 = MyClass2()
>>> print(obj1 + obj2)
这是__radd__+的结果
18. __ str__()与__repr__()
类对象的两个特殊方法用于自定义并返回实例对象的字符串表示形式
- 交互式命令行中直接打印一个实例对象时:
mc: 如果有__repr__方法会自动调用该方法,如果没有则返回实例对象对应的类对象和实例对象在内存中的地址
当有repr方法时 __ repr__> mc
>>> class MyClass(object):
>>> pass
>>> mc = MyClass()
>>> #返回类型的内存地址
>>> mc
<__main__.MyClass object at 0x0000000006D0C390>
>>>
>>> class MyClass4(object):
>>> def __str__(self):
>>> return "__str__被调用"
>>> def __repr__(self):
>>> return "__repr__被调用"
>>> mc = MyClass4()
>>> #repr被调用
>>> mc
__repr__被调用
- 用内置函数print打印实例对象时:
当类中没有str和repr时,返回实例对象对应的类对象和实例对象在内存中的地址
当类中只有str特殊方法时自动调用该方法
当类中只有repr时返回时自动调用该方法
当类中有str和repr时自动调用str方法 str > repr
>>> class MyClass(object):
>>> pass
>>> mc = MyClass()
>>> #返回类型的内存地址
>>> print(mc)
<__main__.MyClass object at 0x0000000006D0C390>
>>>
>>> class MyClass4(object):
>>> def __str__(self):
>>> return "__str__被调用"
>>> def __repr__(self):
>>> return "__repr__被调用"
>>> mc = MyClass4()
>>>
>>> print(mc)
__str__被调用
- 当调用内置函数__str__创建字符串并且实参是一个实例对象时:
同print打印实例对象
当类中没有str和repr时,返回实例对象对应的类对象和实例对象在内存中的地址
当类中只有str特殊方法时自动调用该方法
当类中只有repr时返回时自动调用该方法
当类中有str和repr时自动调用str方法
>>> class MyClass(object):
>>> pass
>>>
>>> mc = MyClass()
>>> str(mc)
<__main__.MyClass object at 0x0000000006D0C390>
>>>
>>> class MyClass4(object):
>>> def __str__(self):
>>> return "__str__被调用"
>>> def __repr__(self):
>>> return "__repr__被调用"
>>> mc = MyClass4()
>>> str(mc)
__str__被调用
- 当调用内置函数__repr__创建字符串并且实参是一个实例对象时:
当类中有__repr__时返回时自动调用该方法,没有该方法时返回实例对象对应的类对象和实例对象在内存中的地址
>>> class MyClass1(object):
>>> pass
>>> class MyClass2(object):
>>> def __str__(self):
>>> return "__str__被调用"
>>> class MyClass3(object):
>>> def __str__(self):
>>> return "__str__被调用"
>>> def __repr__(self):
>>> return "__repr__被调用"
>>> mc1 = MyClass1()
>>> mc2 = MyClass2()
>>> mc3 = MyClass3()
>>> repr(mc1)
<__main__.MyClass object at 0x0000000006D0C390>
>>> repr(mc2)
<__main__.MyClass object at 0x0000000006D0C390>
>>> repr(mc3)
__repr__被调用
注:
通常情况下,类对象的特殊方法__str__()与__repr__()的实现代码是一样的,所以实现了其中一个后,可以把其方法名赋值给另一个方法名
class MyClass(object):
def __str__(self):
return"实例对象的字符串表示形式"
__repr__ = __str__
内置函数str()与repr()的异同:
相同点:str()和repr()都返回对象的字符串表示
不同点:
- str()的返回值是给用户看的
- repr()的返回值是给程序开发者看的,是为调试服务的