关于私有化问题 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
sudo987
V2EX    Python

关于私有化问题

  •  
  •   sudo987 2016-06-21 18:10:40 +08:00 4274 次点击
    这是一个创建于 3474 天前的主题,其中的信息可能已经有所发展或是发生改变。

    很简单的一段代码,觉得基类的同名方法应该会被子类覆盖,但是并没有,求解。

    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 
    27 条回复    2016-06-22 09:44:16 +08:00
    GreatMartial
        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
    你看一下,能否解决你的问题。
    hitmanx
        2
    hitmanx  
       2016-06-21 18:24:31 +08:00
    f = __f 估计在第一次 evaluate class P 时就被赋值了,不会在后来初始化 class C 时再更改了。

    你可以把 f = __f 去掉,然后在 P.__init__()里直接调用__f()试试
    9hills
        3
    9hills  
       2016-06-21 18:25:09 +08:00
    C 和 P 有同名方法么?没看到啊?
    sudo987
        4
    sudo987  
    OP
       2016-06-21 18:25:29 +08:00 via iPhone
    @GreatMartial 直接说问题在哪儿不好么?
    sudo987
        5
    sudo987  
    OP
       2016-06-21 18:26:58 +08:00 via iPhone
    @9hills 基类中的__f()由于私有化其实是_P__f(),子类有同名方法
    kier
        6
    kier  
       2016-06-21 18:29:50 +08:00
    @sudo987 你这有点想当然啊,又不是外部调用,直接方法调用方法,哪还需要考虑私有?
    sudo987
        7
    sudo987  
    OP
       2016-06-21 18:29:55 +08:00 via iPhone
    @hitmanx 谢谢回复,那肯定可以,不想靠猜测,想要求解。
    sudo987
        8
    sudo987  
    OP
       2016-06-21 18:30:59 +08:00 via iPhone
    @kier 官方文档看到这种例子,不解,于是求问。
    kier
        9
    kier  
       2016-06-21 18:32:45 +08:00
    @sudo987 麻烦吧官方链接发出来看看?
    9hills
        10
    9hills  
       2016-06-21 18:34:52 +08:00
    @sudo987 Python 什么时候多了这种 Magic 。。给个文档我看看
    9hills
        11
    9hills  
       2016-06-21 18:35:45 +08:00
    另外 Python 是没有私有方法的,所有方法都是 Public 的,你再怎么加下划线也没用。。。
    kier
        12
    kier  
       2016-06-21 18:37:05 +08:00
    python 没有严格意义的私有方法,只是在__开头的方法,在外部调用的时候,要改下名调用,但是如果是方法调方法,不需要改名的
    sudo987
        13
    sudo987  
    OP
       2016-06-21 18:38:23 +08:00
    @9hills 求解什么叫私有化?
    sudo987
        14
    sudo987  
    OP
       2016-06-21 18:40:10 +08:00
    严不严格无所谓,我只是不明白这段代码的输出为什么会这样,求解。
    sudo987
        15
    sudo987  
    OP
       2016-06-21 18:41:39 +08:00
    hitmanx
        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
    kier
        17
    kier  
       2016-06-21 18:43:43 +08:00
    你再 init 里面调用的是 self.f(),又不是 self.__f(),那肯定是执行 print 'i am P'啦
    9hills
        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 和语法含义在里面,你仔细看就明白了
    sudo987
        19
    sudo987  
    OP
       2016-06-21 18:46:14 +08:00
    @hitmanx 自己试过,这种方法可以输出想要的结果,不明白加上 f = __f 后为什么结果不是想要的。
    kier
        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 这个你能理解不?
    sudo987
        21
    sudo987  
    OP
       2016-06-21 19:26:05 +08:00
    自己搞明白了,这个问题跟私有化没有关系,换成普通名字问题依旧,问题出在实例化顺序上, f = __f 存在于基类,属于类变量,且执行时机早于父类的__init__()更早于基类的__init__(),所以其实 f 的指向已经固定了,就是父类的__f(),且在子类没有对 f 的赋值操作,所以,即使子类覆盖了父类的同名方法__f(), f 的指向早就固定在父类的__f()了,所以才有 i am P 的输出。只有 @hitmanx 说对了。
    sudo987
        22
    sudo987  
    OP
       2016-06-21 19:38:56 +08:00 via iPhone
    说错了,更早于子类。
    kier
        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 楼的回复,就是想表达这么个意思
    好吧,下次我回答问题,一定好好看看题目!
    sudo987
        24
    sudo987  
    OP
       2016-06-21 20:52:23 +08:00
    @kier 嗯嗯。
    happywowwow
        25
    happywowwow  
       2016-06-21 21:39:23 +08:00
    @9hills
    p = P()
    print dir(p)
    print dir(c)
    你可以看到['_P__f'......]
    sudo987
        26
    sudo987  
    OP
       2016-06-21 23:24:14 +08:00 via iPhone
    @9hills 回答个问题跟放炮似的,回答的对也就不说什么了,况且你的回复跟我的问题完全不搭边,呵呵,“你的标题你问我?”,会说话么?你爱答不答,没人逼你,别在这儿影响我心情。
    qian19876025
        27
    qian19876025  
       2016-06-22 09:44:16 +08:00
    我晕 这标题 差点以为是 360 的人问私有化
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     5202 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 27ms UTC 03:39 PVG 11:39 LAX 19:39 JFK 22:39
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86