推荐学习书目
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  ›  Python

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

  •  
  •   leyle · Aug 1, 2014 · 4791 views
    This topic created in 4328 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   ·   3097 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 45ms · UTC 13:51 · PVG 21:51 · LAX 06:51 · JFK 09:51
    ♥ Do have faith in what you're doing.