很简单的一段代码,觉得基类的同名方法应该会被子类覆盖,但是并没有,求解。
class P(object):
def __f(self):
print 'i am P'
f = __f
def __init__(self):
self.f()
class C(P):
def _P__f(self):
print 'i am C'
c = C() # i am P
1
GreatMartial 2016-06-21 18:21:24 +08:00 via Android
小白一枚,昨晚刚看继承与包含,
https://flyouting.gitbooks.io/learn-python-the-hard-way-cn/content/learn-python-the-hard-way-exercise44.html 你看一下,能否解决你的问题。 |
2
hitmanx 2016-06-21 18:24:31 +08:00
f = __f 估计在第一次 evaluate class P 时就被赋值了,不会在后来初始化 class C 时再更改了。
你可以把 f = __f 去掉,然后在 P.__init__()里直接调用__f()试试 |
3
9hills 2016-06-21 18:25:09 +08:00
C 和 P 有同名方法么?没看到啊?
|
4
sudo987 OP @GreatMartial 直接说问题在哪儿不好么?
|
11
9hills 2016-06-21 18:35:45 +08:00
另外 Python 是没有私有方法的,所有方法都是 Public 的,你再怎么加下划线也没用。。。
|
12
kier 2016-06-21 18:37:05 +08:00
python 没有严格意义的私有方法,只是在__开头的方法,在外部调用的时候,要改下名调用,但是如果是方法调方法,不需要改名的
|
14
sudo987 OP 严不严格无所谓,我只是不明白这段代码的输出为什么会这样,求解。
|
15
sudo987 OP |
16
hitmanx 2016-06-21 18:42:41 +08:00
@sudo987
class P(object): def __f(self): print('i am base') def __init__(self): self.__f() class C(P): def _P__f(self): print('i am derived') c = C() # i am P 输出为 i am derived |
17
kier 2016-06-21 18:43:43 +08:00
你再 init 里面调用的是 self.f(),又不是 self.__f(),那肯定是执行 print 'i am P'啦
|
18
9hills 2016-06-21 18:44:39 +08:00
@sudo987 你的标题你问我?
文档里写的很明白:“ Private ” instance variables that cannot be accessed except from inside an object don ’ t exist in Python. 而且也没有你这种用法。。。下划线没有任何 Magic 和语法含义在里面,你仔细看就明白了 |
20
kier 2016-06-21 18:52:53 +08:00
>>> def a():
... print 'a' ... >>> >>> b = a >>> def a(): ... print 'new a' ... >>> a() new a >>> b() a @sudo987 这个你能理解不? |
21
sudo987 OP 自己搞明白了,这个问题跟私有化没有关系,换成普通名字问题依旧,问题出在实例化顺序上, f = __f 存在于基类,属于类变量,且执行时机早于父类的__init__()更早于基类的__init__(),所以其实 f 的指向已经固定了,就是父类的__f(),且在子类没有对 f 的赋值操作,所以,即使子类覆盖了父类的同名方法__f(), f 的指向早就固定在父类的__f()了,所以才有 i am P 的输出。只有 @hitmanx 说对了。
|
22
sudo987 OP 说错了,更早于子类。
|
23
kier 2016-06-21 20:06:20 +08:00
其实在 python 里, function 跟数字,字符串是一样的
比如 a = 1; b = a; a =2; 这时 b 的取值是什么呢,相信你也能一样看出是 1 ,如果把 1,2 换成一个函数体呢?其实效果也是一样的, b 还是原来的函数,类方法也是同样的道理,改了 P.__f ,但是 P.f 还是原来的那个方法,并没有改变 由于看到 5 楼你的回复,被带偏了,就直接答到私有方法上面去了,但是后来我在 20 楼的回复,就是想表达这么个意思 好吧,下次我回答问题,一定好好看看题目! |
25
happywowwow 2016-06-21 21:39:23 +08:00
|
26
sudo987 OP @9hills 回答个问题跟放炮似的,回答的对也就不说什么了,况且你的回复跟我的问题完全不搭边,呵呵,“你的标题你问我?”,会说话么?你爱答不答,没人逼你,别在这儿影响我心情。
|
27
qian19876025 2016-06-22 09:44:16 +08:00
我晕 这标题 差点以为是 360 的人问私有化
|