读 SocketServer.py 遇到的一个问题,父类可以调用子类的方法? - 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
leyle
V2EX    Pytho

SocketServer.py 遇到的一个问题,父类可以调用子类的方法?

  •  
  •   leyle Aug 1, 2014 4734 views
    This topic created in 4302 days ago, the information mentioned may be changed or developed.
    1、现象:
    最近使用到了SocketServer.py 这个包,就顺便学习一下它的实现,在阅读的过程中,发现
    BaseServer 中的 _handle_request_noblock()函数中 有一句

    request, client_address = self.get_request()

    而这个 get_request()方法是在继承于BaseServer的 TCPServer 和UDPServer 中实现的,


    三个的关系的定义是:

    class BaseServer:

    class TCPServer(BaseServer):

    class UDPServer(TCPServer):

    2、疑问:
    父类可以调用子类中的方法么?
    还是说我对这里代码的理解有误?
    希望明白的朋友给我解一下惑或者指引一下相关的资料,谢谢拉!
    Supplement 1    Aug 1, 2014
    多谢 @clino 的解释

    这里的设计是不是不好,应该在BaseServer中定义一个

    def get_requeset(self):
    pass

    然后再在去子类中改写?让结构更清晰一些?
    Supplement 2    Aug 1, 2014
    哦,因为 get_request() 有返回值,所以无法在父类中仅仅的定义一个空函数,不然要报错
    9 replies    2014-08-02 00:06:58 +08:00
    clino
        1
    clino  
       Aug 1, 2014   1
    不用从"父类可以调用子类中的方法"这种角度去看,而从对象生成以后的执行调用这个角度去看就行了,对象调用的时候 self.get_request() 就是调用自己这个对象里的 get_request() 方法啊,那这个方法具体是哪个,是由对象是从哪个类产生决定的
    datou552211
        2
    datou552211  
       Aug 1, 2014   1
    这里的self不是指BaseServer或者它的实例。
    leyle
        3
    leyle  
    OP
       Aug 1, 2014
    @clino 多谢,一下子就明白了。
    julyclyde
        4
    julyclyde  
       Aug 1, 2014
    无所谓啊反正是执行的时候才执行的,而不是编译期
    x10ng
        5
    x10ng  
       Aug 1, 2014
    动态类型就是这样子,只要运行期的对象有该方法就可以。
    maemual
        6
    maemual  
       Aug 1, 2014   1
    第二条附言不对吧,就算声明了这个方法,就pass一下,也不会报错啊。

    都说了python是动态类型,只需要在运行时有这个方法,也就是继承的TCPServer、UDPServer有这个方法的正确实现就行了。

    这里的设计是不是不好的问题,确实不怎么好说。在我的理解,这里的BaseServer不是用来给用户使用的,Python的文档里也没有提到这个东西,所以默认他写这个基类是给自己方便下面实现TCPServer和UDPServer用的。所以只要他自己去实现对应的方法就行了。

    同样,在Tornado 4.0的源码里,有很多地方的基类,比如tcpserver.py里214行声明了handle_stream,在255行调用了,但是只是简单的raise NotImplementedError()。本人是觉得Tornado的这种方式更加好一些。
    kamushin
        7
    kamushin  
       Aug 1, 2014
    @maemual 同意这位。在看Tornado代码的时候我也发现了这种raise NotImplementedError()的做法,我觉得这样会比较好。
    shyrock
        8
    shyrock  
       Aug 1, 2014
    声明同名空方法的方式更符合静态语言的思想。
    从代码的可读性来说,这个方法对习惯静态语言的开发者更友好。
    incompatible
        9
    incompatible  
       Aug 2, 2014
    赞同 @maemual 的方式和 @shyrock 的观点

    刚刚转python的java码农表示:dynamic binding用起来虽然爽,一旦工程规模大了,迟早会留坑
    About     Help     Advertise     Blog     API     FAQ     Solana     3199 Online   Highest 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 100ms UTC 14:39 PVG 22:39 LAX 07:39 JFK 10: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