鱼C论坛

 找回密码
 立即注册
查看: 2521|回复: 6

关于课程第11节魔法方法:算术运算的一个疑惑

[复制链接]
发表于 2017-3-1 20:25:30 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 izhy3938 于 2017-3-1 21:24 编辑

首先先看一个对实例的理解代码如下:
__metaclass__ = type 

class Try_int(int):
        def __init__(self, value):
                self.num = value 
                
a = Try_int(3)
print a.num  #结果输出3
值(实参)3通过行参value被类Try_int内属性num所引用,所以我们知道了参数最终传递的归属。再看课程中小甲鱼的例子
__metaclass__ = type 

class Try_int(int):
        def __add__(self, other):
                return int(self) + int(other)
                
a = Try_int(3)
让我困惑的是,小甲鱼课程中这个类Try_int(),定义的时候并没有给出形式参数,那么当实例化以后,a = Try_int(3),这个实参3,被谁引用?或者换种说法,这个实参3放在了这个类的什么地方?(准确的说法是被类中那个属性引用?)实参3传递到哪里去了?突然想到,小甲鱼例子中 a = Try_int(3)是不是等同于 a = int(3)等同于 a = 3(有附加条件就是这个类的实例相加的时候自动触发类定义时候__add__(self, other)方法)。然后我验证了一下
__metaclass__ = type 

class Try_int(int):
        def __init__(self, value):
                self.num = value 
                
a = Try_int(3)
print a.num #输出3
print a #输出3
那只能这样里解了,其实例子就是给变量赋值,只是加上了附加条件自动触发魔法方法。
让我感到意外,或者不可理解的是,上例中 a.num = 3 而且竟然 a = 3, 一个类属性的值,为啥实例化后竟然可以成为实例的值。因为一直拿函数的方式理解类,函数内如任何变量的值,如果不是明确的返回该值,一般函数的返回值不可能等于函数中任何变量的值(特殊构造的除外),但对象实例化的值竟(我一直按照函数的返回值理解)然等于其内部属性(我一般按照函数内部变量的赋值理解)的值(就这个例子而言),用函数的观点来看,让我很意外。
突然有想起一个有趣的问题:
__metaclass__ = type 

class Try_int(int):
        def __add__(self, other):
                return __sub__(self, other)
                
a = Try_int(3)
b = 4
如上例,实例a的中__add__(self,other)被改成了减法,而b实例属于a实例父类创建的实例,自然b实例的__add__(self, other)方法没有被修改
如果这两个实例相加,是遵循减法呢还是遵循加法呢?
当然可以自己调试print看一下,其实我感觉python肯定在它的说明书中有这样的规定,规定这样情况下是遵循加法还是减法。而如何根据问题去查找说明书的相关说明,不知道各位大神有没有相关的经验可以传授。
个人感觉,必须会英文,查找关键字。可惜我的英文不好,没法做到用精准的英文关键字去网上搜问题以及答案。
所以又变成了,解决一个问题,就必须花精力去搞定更困难的问题。这才让学习这件事本身变得困难富有挑战。你想20天学会某某某,我认为是痴心妄想。当然我指的的完全掌握一种技术,让它融入你的内心,就像小说中说的人剑合一的境界。
补充:刚才又去搜了搜,原来很多语法内建函数都是魔法方法的封装,魔法方法就python来说是其底层:
对于内置的对象来说(比如整数、表、字符串等),它们所需要的特殊方法都已经在Python中准备好了。而用户自己定义的对象也可以通过增加特殊方法,来实现自定义的语法。特殊方法比较靠近Python的底层,许多Python功能的实现都要依赖于特殊方法。我们将在以后看到更多的例子。

                               
登录/注册后可看大图


Python的许多语法都是基于其面向对象模型的封装。对象模型是Python的骨架,是功能完备、火力强大的大黄蜂。但是Python也提供更加简洁的语法,让你使用不同的编程形态,从而在必要时隐藏一些面向对象的接口。正如我们看到的Camaro跑车,将自己威风的火药库收起来,提供方便人类使用的车门和座椅。







想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2017-3-2 14:04:15 | 显示全部楼层
为啥我的第11个不是魔法算法。
膜拜,看不懂~
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-3-2 20:33:31 | 显示全部楼层
1、“小甲鱼课程中这个类Try_int(),定义的时候并没有给出形式参数,那么当实例化以后,a = Try_int(3),这个实参3,被谁引用?”
答:类Try_int继承了类int,所以也继承了类int中的__init__方法,实参3会传给这个方法。
2、“让我感到意外,或者不可理解的是,上例中 a.num = 3 而且竟然 a = 3, 一个类属性的值,为啥实例化后竟然可以成为实例的值。”
答:还是因为Try_int继承了int,所以获得了int的表示方法。另外a.num和a的类型是不一样的,一个是<class 'int'>,一个是<class '__main__.Try_int'>。
3、“实例a的中__add__(self,other)被改成了减法,而b实例属于a实例父类创建的实例,自然b实例的__add__(self, other)方法没有被修改,如果这两个实例相加,是遵循减法呢还是遵循加法呢?”
答:你的代码有误,应该 return int.__sub__(self, other),结果遵循减法,因为__add__是左触发的,即a+b取决于a对方法__add__的定义,如果b+a则遵循加法。另外请参考__radd__方法,它和__add__相反,是右触发。
4、“可惜我的英文不好,没法做到用精准的英文关键字去网上搜问题以及答案。”
答:虽然我的英文很好,但是Google比我更能帮你。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-3-3 20:27:50 | 显示全部楼层
因为try_int 继承了int 中的__init__
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-3-4 18:21:48 | 显示全部楼层
overlord 发表于 2017-3-2 20:33
1、“小甲鱼课程中这个类Try_int(),定义的时候并没有给出形式参数,那么当实例化以后,a = Try_int(3),这 ...

这里面有个对初学者不友好的悖论。你说实参3传递给了父类的__init__方法,但是我不知道父类中__init__方法是怎么定义的,我怎么知道父类的__init__方法定义的时候定义了形参来接受参数?
你说对吧。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-3-5 19:37:16 | 显示全部楼层
izhy3938 发表于 2017-3-4 18:21
这里面有个对初学者不友好的悖论。你说实参3传递给了父类的__init__方法,但是我不知道父类中__init__方 ...

继承就是这样,父类有的,子类也都有。。当然子类也可以做更改。关于int类或object类具体是怎么实现的,那就要更深入的学习了。。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-3-5 19:41:27 | 显示全部楼层
overlord 发表于 2017-3-5 19:37
继承就是这样,父类有的,子类也都有。。当然子类也可以做更改。关于int类或object类具体是怎么实现的, ...

问题是教材又没有告诉我父类__init__方法有什么,我怎么父类__init__方法里面有个接收实参的形式参数?你的观点我明白,但是对初学者,有点事后诸葛亮的味道,毕竟我不知道啊
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-10-6 22:28

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表