第十周作业-面向对象进阶
1. 集合(set)元素去重的判断依据是什么
在调用set()时,每加入一个元素会调用__hash__方法得到一个哈希值,如果该值与集合中其它元素的哈希值不同则直接判断不重复并加入集合;如果哈希值有冲突,则再调用__eq__方法判断两个值是否相等,结果为False时也加入集合。
2. 总结本周视频讲解魔术方法的作用及什么情况会执行到该方法
运算符相关的魔术方法:
| 方法 | 意义 |
|---|---|
__new__ |
实例化一个对象,该方法需要返回一个对象,如果该值不是cls的实例,则不会调用__init__方法,该方法永远时静态方法 |
__str__ |
使用print、str、format函数时调用该方法,返回一个字符串,如果没有定义则调用__repr__方法,如果都没有定义则返回object类定义的该方法(返回一个内存地址信息) |
__repr__ |
使用内建函数repr()对一个对象获取字符串表达,返回一个字符串 |
__bytes__ |
内建函数bytes()调用,返回一个bytes对象 |
__bool__ |
内建函数bool()返回布尔值,如果没有定义此函数则调用__len__函数,长度非0为真,如果都没定义则返回真 |
__lt__ |
比较运算符重载,进行<操作时调用 |
__le__ |
比较运算符重载,进行<=操作时调用 |
__eq__ |
比较运算符重载,进行==操作时调用,可以判断不等于 |
__gt__ |
比较运算符重载,进行>操作时调用,可以判断小于 |
__ge__ |
比较运算符重载,进行>=操作时调用,可以判断小于等于 |
__ne__ |
比较运算符重载,进行!=操作时调用 |
__add__ |
算数运算符重载,进行+操作时调用 |
__sub__ |
算数运算符重载,进行-操作时调用 |
__mul__ |
算数运算符重载,进行*操作时调用 |
__truediv__ |
算数运算符重载,进行/操作时调用 |
__mod__ |
算数运算符重载,进行%操作时调用 |
__floordiv__ |
算数运算符重载,进行//操作时调用 |
__pow__ |
算数运算符重载,进行**操作时调用 |
__divmod__ |
算数运算符重载,进行divmod操作时调用 |
__iadd__ |
运算符重载,进行+=操作时调用 |
__isub__ |
运算符重载,进行-=操作时调用 |
__imul__ |
运算符重载,进行*=操作时调用 |
__itruediv__ |
运算符重载,进行/=操作时调用 |
__imod__ |
运算符重载,进行%=操作时调用 |
__ifloordiv__ |
运算符重载,进行//=操作时调用 |
__ipow__ |
运算符重载,进行**=操作时调用 |
__sub__ |
运算符重载,进行/=操作时调用 |
容器相关的魔术方法:
| 方法 | 意义 |
|---|---|
__len__ |
内建函数len(),返回>=0的整数 |
__iter__ |
迭代容器对象时调用,返回一个新的迭代器对象 |
__contains__ |
in成员运算符,没有实现则调用__iter__遍历 |
__getitem__ |
实现self[key]访问。序列对象,key接受整数为索引,或者切片。对于set和dict,key为hashable。key不存在引发KeyError异常 |
__setitem__ |
和 __getitem__ 的访问类似,是设置值的方法 |
__missing__ |
字典或其子类使用__getitem__()调用时,key不存在执行该方法 |
反射相关的魔术方法:
运行时,runtime,区别于编译时,指的是程序被加载到内存中执行的时候。
反射,reflection,指的是运行时获取类型定义信息。
一个对象能够在运行时,像照镜子一样,反射出其类型信息。
简单说,在Python中,能够通过一个对象,找出其type、class、attribute或method的能力,称为反射或者自省。
具有反射能力的函数有type()、isinstance()、callable()、dir()、getattr()等
| 内建函数 | 意义 |
|---|---|
getattr(object,name[, default]) |
通过name返回object的属性值。当属性不存在,将使用default返回,如果没有default,则抛出AttributeError。name必须为字符串 |
setattr(object,name, value) |
object的属性存在,则覆盖,不存在,新增 |
hasattr(object,name) |
判断对象是否有这个名字的属性,name必须为字符串 |
| 魔术方法 | 意义 |
|---|---|
__getattr__() |
当通过搜索实例、实例的类及祖先类查不到属性,就会调用此方法 |
__setattr__() |
通过 . 访问实例属性,进行增加、修改都要调用它 |
__delattr__() |
当通过实例来删除属性时调用此方法 |
__getattribute__ |
实例所有的属性调用都从这个方法开始 |
实例属性查找顺序为:
实例调用__getattribute__() --> instance.__dict__ --> instance.__class__.__dict__ --> 继承的祖先类(直到object)的__dict__ --> 调用__getattr__()
3. 结合本周所学内容,实现如下类:
class Ob:
pass
执行以下操作:
a = Ob('tom')
b = Ob('tom')
print('a: ', a)
a[0] = 'a'
print('a:', a)
a * 3
print('len: ', len(a))
del a[1]
print('a: ', a)
print('set: ', {a, b})
其输出如下:
a: ['1', '2']
a: ['a', '2']
len: 6
a: ['a', 'a', '2', 'a', '2']
set: {<Ob name=tom items=['a', 'a', '2', 'a', '2']>}
class Ob:
def __init__(self, name):
self.name = name
self.items = ['1', '2']
def __str__(self): # 解决print中的显示
return str(self.items)
def __repr__(self): # 解决集合中的展示
return '<{} name={} items={}>'.format(self.__class__.__name__, self.name, self.items)
def __setitem__(self, key, value): # 解决以列表下标方式设置值
self.items[key] = value
def __mul__(self, other): # *运算符重载
self.items *= other
def __len__(self): # 显示长度
return len(self.items)
def __delitem__(self, key): # 删除元组元素
self.items.pop(key)
def __hash__(self): # 与__eq__方法结合在集合中去重
return id(self.name)
def __eq__(self, other):
return self.name == other.name
a = Ob('tom')
b = Ob('tom')
print('a: ', a)
a[0] = 'a'
print('a:', a)
a * 3
print('len: ', len(a))
del a[1]
print('a: ', a)
print('set: ', {a, b})
结果如图:


浙公网安备 33010602011771号