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
fuxkcsdn
V2EX  ›  Python

有办法在 subclass 中修改 parent class 的方法,使其返回某个变量吗?( parent class 的该方法无返回值)

  •  
  •   fuxkcsdn · 2017-06-28 22:28:42 +08:00 · 1995 次点击
    这是一个创建于 2711 天前的主题,其中的信息可能已经有所发展或是发生改变。

    代码大致如下,其中 parent class 是某个开源库类

    # parent class
    class A(object):
        # ... bala bala ...
        def test(self, url):
            # ... bala bala ...
            rsp = self.http.send(url=url)
            rsp = json.loads(rsp.content)
            self._session = self._session_type(rsp['a'], rsp['b'])
    
    # subclass
    class B(A):
        def test(self, url):
            # ... bala bala ...
            rsp = self.http.send(url=url)
            rsp = json.loads(rsp.content)
            self._session = self._session_type(rsp['a'], rsp['b'])
            self._xx = rsp['xx']
    

    如果 A.test 有将 rsp 返回的话,那 subclass 就只需要

    class B(A):
        def test(self, url):
            rsp = super(self.__class__, self).test(url)
            self._xx = rsp['xx']
    

    所以...是否有办法可以让 parent class 的 test 方法返回 rsp 呢?(排除修改 parent class 源码的方法)

    第 1 条附言  ·  2017-06-28 23:54:56 +08:00

    2楼 的方法测试可行,实际代码片段测试,tracert 的覆盖方法会比复制父类代码的覆盖方法慢上9~10倍(timerit repeat number = 100000)

    import sys
    
    # parent class
    class A(object):
        # ... bala bala ...
        def test(self, url):
            # ... bala bala ...
            rsp = self.http.send(url=url)
            rsp = json.loads(rsp.content)
            self._session = self._session_type(rsp['a'], rsp['b'])
    
    # subclass
    class B(A):
        def test(self, url):
            _locals = {}
    
            def tracert(frame, event, arg):
                if event == 'return':
                    _locals.update(frame.f_locals.copy())
    
            sys.setprofile(tracert)
            
            try:
                super(self.__class__, self).test(url)
            finally:                       
                sys.setprofile(None)       
            rsp = _locals['rsp']
            self._xx = rsp['xx']
    
    6 条回复    2017-06-29 07:41:59 +08:00
    douxie
        1
    douxie  
       2017-06-28 23:14:07 +08:00
    B 中的 test 重写一遍 A.test 的实现,不就行了么
    XYxe
        2
    XYxe  
       2017-06-28 23:14:11 +08:00   ❤️ 1
    你的问题是在函数执行结束后获取函数内的变量,一个可行的方法:
    Hzzone
        3
    Hzzone  
       2017-06-28 23:18:25 +08:00
    子类覆盖父类的方法...
    twistoy
        4
    twistoy  
       2017-06-28 23:30:08 +08:00
    重写一个函数,直接覆盖在 A.test 上面,似乎也可以?
    fuxkcsdn
        5
    fuxkcsdn  
    OP
       2017-06-28 23:46:55 +08:00
    @douxie
    @Hzzone
    我帖子里的例子代码不就是这样写了...因为父类的这方法代码挺多的,感觉复制一遍挺麻烦的...

    @XYxe
    可行,不过要覆盖的这方法挺常用的...这样弄的话挺影响执行效率的(测试了下,大概要慢 9~10 倍)...
    XYxe
        6
    XYxe  
       2017-06-29 07:41:59 +08:00
    @fuxkcsdn #5 肯定会慢啊。还有一个不一定可行的方法,修改 rsp=...之后调用的某个函数,例如这里的 self._session_type:



    这样效率不会有太大影响,但还是要复制一点父类的代码,如果有短一点的函数那可以考虑。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2258 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 22ms · UTC 00:52 · PVG 08:52 · LAX 16:52 · JFK 19:52
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.