一、 反运算符

当对应的操作数不支持调用时,反运算数被调用(参考资料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. shell基础:位置参数变量

    位置参数名称,作用不变.变得是传入参数. 抽象问题,大多为年长资格老师少数年轻老师,故而问的技术细节少,抽象理论知识多,比如什么是软件工程,问什么会有软件工程.有事注重的是品质,有的注重出身. 每种都 ...

  2. composer----------composer初体验,如何安装,如何下载

    最近PHP里面比较火的一款框架laravel,想学一下看下这个框架到底哪里好.这款框架的中文官网激励推荐composer,没办法就去学了一些composer.结果整了半天,还不如看一段短视频学的容易. ...

  3. MyBatis基础入门《八》查询参数传入Map

    MyBatis基础入门<八>查询参数传入Map 描述: 在执行select查询数据的时候,方法传入的参数是java.util.Map类型. 接口方法: xml文件 注意: 书写SQL语句的 ...

  4. webpack打包二进制文件报错

    错误示例,如下图所示: 修改webpack的module部分的rules,在其中添加一下代码: { test: /\.woff[0-9]{0,}$/, loader: "url-loader ...

  5. jQuery绑定事件方法及区别(bind,click,on,live,one)

    第一种方式: ? 1 2 3 4 5 $(document).ready(function(){  $("#clickme").click(function(){  alert(& ...

  6. sql2008升级到r2提示:检查当前是否正确配置了报表服务器、数据库服务器是否正在运行以及您是否有权访问

    sql2008升级到r2提示:检查当前是否正确配置了报表服务器.数据库服务器是否正在运行以及您是否有权访问 解决方法:把服务开启ok

  7. 20155228 2016-2017-2 《Java程序设计》第1周学习总结

    20155228 2016-2017-2 <Java程序设计>第1周学习总结 教材学习内容总结 这部分内容是以教材为基础,根据个人的理解来描述的,有的地方的理解和表述可能不规范甚至不正确, ...

  8. MySql 存储过程 退出

    mysql不支持quit, exit或return的方式退出编写存储过程时,为了业务规则需要,我们可能需要提前退出存储过程那么,我们可以利用leave label方式模拟实现quit退出的效果应用示例 ...

  9. python操作Mysql数据库示例

    python库:pymysql 安装:install pymysql.mysql数据库 一.连接数据库.创建speder库.查询版本. import pymysql ##链接数据库 db = pymy ...

  10. 刨根究底字符编码之—UTF-16编码方式

    在网上已经转悠好几天了, 这篇文章让我知道了UTF-16的前世今生, 感谢作者https://cloud.tencent.com/developer/article/1384687 1. UTF-16 ...