一、 反运算符

当对应的操作数不支持调用时,反运算数被调用(参考资料Lhttps://fishc.com.cn/thread-48793-1-1.html )

1、对象(a+b)相加,如果对象a有__add__方法,请问b对象__radd__方法会被调用吗?

不会被调用

>>> class Iinit(int):
def __radd__(self,other):
print('__radd__被调用!')
return int.__sub__(self,other) >>> a = Iinit('')
>>> b = Iinit('')
>>> a+b >>> +b
__radd__被调用! >>> #a+b时,调用了__add__,则你不会调用__radd__ #+b时,由于没有找到__add__,则调用了__radd__ (何时调用__radd__方法:当a对象的__add__没有实现或者不支持相应操作时,b会自动调用__radd__方法

2、如何在继承中调用基类的方法

基类的方法:在程序中,继承描述的多个类之间的关系,如果一个类A中的方法和属性可以被复用,就可以通过继承传递到B类,A类就被称为父类也叫做基类,那么B类就被称为子类也叫派生类

#子类可以直接调用父类的属性和方法
class A:
def __init__(self):
self.study='学习打卡第一天!' def learn(self):
print('为梦想奋斗!') class B(A):
def catch(self):
print('喝一壶老酒让我回回头!') b = B()
b.learn()
b.catch()
print(b.study) 为梦想奋斗!
喝一壶老酒让我回回头!
学习打卡第一天!
>>>

使用super这个BIF

class Base:
def __init__(self):
print(' this is function of Base!') class A(Base):
def __init__(self):
super().__init__()
print('this is function of A') class B(Base):
def __init__(self):
super().__init__()
print('this is function of B') class C(A,B):
def __init__(self):
super().__init__()
print('this is function of C') c = C() 打印输出:
this is function of Base1
this is function of B
this is function of A
this is function of C

为什么super()函数重写之后,Base()函数只调用了一次初始化函数

要理解为什么会这样,首先的看python针对每一个定义的类,都会计算出一个方法解析顺序(MRO)列表,MRO列表只是对所有的基类进行了简单的排序,具体如下:

>>> print(C.__mro__)
(<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class '__main__.Base'>, <class 'object'>)
>>> print(type(C.__mro__))
<class 'tuple'>

由上面打印的内容可以看出,MRO列表是以元组的形式存储的(tuple),然后从左的子类开始查找,直到查到到最上层,无法查找为止

MRO列表是如何确定的呢?Python采用的是c3线性化处理方式,简单的说就是满足以下三种条件:

1)、先检查子类,在检查父类选择,

2)、有多个父类(多重继承),按照MRO列表的顺序依次检查

3)、如果下一个类中,出现两个合法的选择,那就继续从父类中选择(避免重复继承,保证每个父类只继承一次)

|--super()还有一个更加神奇的用法,那就是并不直接关联父类,但是仍然可以遍历所有的父类,原因在于重新定义的方法(如下例中的:__init__)中使用了super()并且只使用了一次

class A:
def __init__(self):
print("this is A") class B:
def __init__(self):
print('this is B')
super().__init__() class C(B,A):
pass c = C()
执行结果:
this is B
this is A
=======================
class A:
def __init__(self):
print("this is A") class B:
def __init__(self):
print('this is B')
super().__init__() class C(A,B):
pass
执行结果:
this is A

观察以上两端代码,为什么会有这样的差异化呢,第一个C(B,A)就会把A,B两个类的内容都打印出来呢?第二个C(A,B)只是把A类中的内容打印出来呢

原因在于:super()的MRO特性,此特性在于从左的子类开始查找,当C(B,A)时,首先会查找B类,然后B类和A类由于super()的MRO(方法解析顺序)会寻找下一个方法,这样就找到了A类,并把A类中的print打印了出来;那为什么C(A,B)没有把B类中的print打印出来呢,怨原因也在于先从左边的A类开始找,结果A类并没有采用super()所以不会寻找下一个方法

>>> print(C.__mro__)
(<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>)
>>> >>> print(C.__mro__)
(<class '__main__.C'>, <class '__main__.B'>, <class '__main__.A'>, <class 'object'>)
>>> 这两端代码就是以上文字说明的最好解释

3、我们要继承的基类是动态的(有时候是A,有时候是B),我应该如何部署我的代码,以便基类可以随意改变

答:可以先为基类定义一个别名,在类定义的时候,使用别名继承你要继承的基类,如此,当你要改变基类的时候,只需要修改给别名赋值的那个语句即可

class BaseClass:
def __init__(self):
print('打印基类BaseClass') BaseAlias = BaseClass # 为基类取别名 class Derived(BaseAlias):
def meth(self):
BaseAlias.meth(self) # 通过别名访问基类 d = Derived() 执行结果:
打印基类BaseClass

4、如何使用类的静态属性

答:类中的静态属性很简单,类中直接定义的属性(没有self)就是静态属性。引用类的静态属性的方法:类名.属性名

class C:
count = #静态属性 def __init__(self):
C.count = C.count+ #类名.属性名的形式引用 def getCount(self):
return C.count c = C()

5、如何使用静态方法,并且说明使用过程中需要注意哪些地方

答:静态方法是类的特殊方法,静态方法只需要在普通方法前面加上@staticmethod 修饰符即可

class C:
def static(arg1,arg2,arg3):
print(arg1,arg2,arg3,arg1+arg2+arg3) def nostatic(self):
print("I love AI") #静态方法不需要self参数,直接用类名.方法名调用。即使是使用了对象去访问,self也不会传进去
>>> c1.static(,,)
Traceback (most recent call last):
File "<pyshell#8>", line , in <module>
c1.static(,,)
TypeError: static() takes positional arguments but were given
>>> C.static(,,)

二、动手题

1、定义一个类,当实例化该类的时候,自动判断传入多少个参数,并显示出来

class C:
def __init__(self,*args):
if not args:
print('并没有传入参数') else:
print('传入了%d个参数,分别是:'%len(args),end='')
for each in args:
print(each,end=' ')
c1 = C(1,'www',20)

2、定义一个单词Word类继承自字符串,重写比较字符串,当两个Word类对象进行比较时,根据单词的长度进行比较大小

加分要求:实例化时如果传入的是带空格的字符串,则取第一个空格前的单词作为参数

class Word(str):
'''存储单词的类,定义比较单词的几种方法 '''
def __new__(cls,word):#重载__new__方法来实现(因为str是不可变类型)
if ' ' in word:
word = word[:word.index(' ')]#利用切片取单词前面的空格 return str.__new__(cls,word) def __gt__(self,other):#定义大于号的行为:x>y调用x.__gt__(y)
return len(self) > len(other) def __lt__(self,other):#定义小于号的行为:x<y调用x.__lt__(y)
return len(self)<len(other) def __ge__(self,other):#定义大于等于号的行为:x>=y调用x.__ge__(y)
return len(self)>=len(other) def __le__(self,other):#定义小于等于号的行为:x<=y调用x.__le__(y)
return len(self)<=len(other) 执行结果:
>>> c1 = Word('  word')
>>> c2 = Word('apple')
>>> c1<c2
True
>>> c1>c2
False
>>> c1<=c2
True
>>> c1>=c2
False
>>>
>>> c1 = Word('  word')
Value contains spaces. Truncating to first space.
>>>

【Python043-魔法方法:算术方法2】的更多相关文章

  1. .NET 基础 一步步 一幕幕[面向对象之方法、方法的重载、方法的重写、方法的递归]

    方法.方法的重载.方法的重写.方法的递归 方法: 将一堆代码进行重用的一种机制. 语法: [访问修饰符] 返回类型 <方法名>(参数列表){ 方法主体: } 返回值类型:如果不需要写返回值 ...

  2. paip。java 高级特性 类默认方法,匿名方法+多方法连续调用, 常量类型

    paip.java 高级特性 类默认方法,匿名方法+多方法连续调用, 常量类型 作者Attilax 艾龙,  EMAIL:1466519819@qq.com 来源:attilax的专栏 地址:http ...

  3. JavaScript【面向对象】-静态方法-私有方法-公有方法-特权方法

    JavaScript面向对象是近年来比较火的一个概念了,由于小弟才疏学浅,虽然做过不少的web项目,看了网上很多深奥的资料和教程,还是对他们深奥 的理论一知半解,前段时间看了点书,总算有了自己的理解, ...

  4. 扩展方法where方法查询不到数据,不会抛异常,也不是返回的null

    如题,“扩展方法where方法查询不到数据,不会抛异常,也不是返回的null”,示例代码如下: Product类: public class Product { private string name ...

  5. iOS系统弃用方法更新方法

    -boundingRectWithSize:options:attributes:context:用法 - (CGSize)sizeWithFont:(UIFont *)font constraine ...

  6. 解决Cell重用内容混乱的几种简单方法,有些方法会增加内存

    重用实现分析 查看UITableView头文件,会找到NSMutableArray*  visiableCells,和NSMutableDictnery* reusableTableCells两个结构 ...

  7. 学JAVA第十三天,方法、方法重载及构造函数

    今天终于不讲狗跳楼的问题了,今天讲了方法,方法重载及构造函数及构造函数重载的课程了. 这里说了有参好无参的,下面讲构造函数重载和方法重载. 其实,这上面写的这些方法,就相当一个模板.想要快速做出产品就 ...

  8. spring aop 切面编程中获取具体方法的方法

    spring 切面编程中获取具体方法的方法 工作中,使用环绕通知,用来捕获异常,然后通过获取方法的返回值,返回不同的数据给到调用方. 由于方法的返回值不同,我们处理异常时,也需要返回不同的格式. 这时 ...

  9. nodejs -- http模块. request() 方法 , get方法.

    1. request方法: 提交评论到慕课网: var http = require('http'); var querystring = require('querystring'); var po ...

  10. python - class内置方法 doc/module/del(析构方法)/cal 方法

    __doc__ # __doc__ #摘要信息 #这个属性不会继承给子类 class Test(): """这是摘要信息""" pass x ...

随机推荐

  1. Sklearn的使用

    初步接触要求时,从上图选自己数据所适用的方法, 首先看数据的样本是否 >50,小于则需要收集更多的数据 然后看问题适合分类.回归.聚类.降维中的哪一大类 Sklearn解决问题的一般步骤: 1. ...

  2. spring之拦截器

    拦截器 实现HandlerInterceptor接口:注册拦截器<mvc:inteceptors> spring和springMVC父子容器的关系 在spring整体框架的核心概念中,容器 ...

  3. LeetCode108.将有序数组转换为二叉搜索树

    将一个按照升序排列的有序数组,转换为一棵高度平衡二叉搜索树. 本题中,一个高度平衡二叉树是指一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1. 示例: 给定有序数组: [-10,-3,0, ...

  4. oracle数据库数值类型

    ---恢复内容开始--- 内容摘自网络 Oracle的数值类型有int,number,float,decimal,numberic等. NUMBER类型   定义   定义格式NUMBER (prec ...

  5. Sitecore xDB基础知识 - 识别用户,联系人,访客,客户

    体验数据库(xDB)是Sitecore平台的关键元素,特别是当您希望将解决方案提升到简单的内容管理要求之外时.它用于跟踪您的用户(即联系人,访客,客户)与您网站的互动方式.营销人员可以使用此数据来了解 ...

  6. codeforces 975C Valhalla Siege

    题意: 有n个巫师站成一列,每个巫师有自己的血量. 一个人射箭攻击他们,每次造成若干点伤害,巫师按照给定的顺序承受伤害,如果伤害大了,那么死掉,伤害落到下一个巫师身上. 如果一轮攻击之后,所有的巫师都 ...

  7. 前端和后台BUG区分方法

    测试工程师不只是负责发现问题,除了发现问题这种基本功外,定位问题,提出解决方案,提出预防方案也是要掌握的技能.这里先说定位问题的要求,定位问题要向深入,前提当然是对功能.产品的流程.开发方案.开发人员 ...

  8. GO富集分析

    GO的主要用途之一是对基因组进行富集分析.例如,给定一组在特定条件下上调的基因,富集分析将使用该基因组的注释发现哪些GO术语被过度表示(或未充分表示). 富集分析工具    用户可以直接从GOC网站的 ...

  9. Ontology Relations

    Overview The following page documents the relations used in the filtered GO ontology. For informatio ...

  10. springboot报错Whitelabel Error Page

    第一次使用springboot没有问题.隔了两天继续看.一直报错Whitelabel Error Page. 重新搭建试了任何方法都错了. 报的就是一个404错误,犯了一个习惯性错误,一般都是loca ...