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

关于函数重载的问题

  •  
  •   wenLiangcan · 2014-02-02 16:44:15 +08:00 via Android · 3402 次点击
    这是一个创建于 3976 天前的主题,其中的信息可能已经有所发展或是发生改变。
    想要写一个 classmethod 和一个同名的普通方法,使得直接通过类名调用时调用的是 classmethod,通过实例则调用普通方法。

    本来通过参数个数来区别,本来至少需要一个参数,所以对其中一个增加作为区分的参数
    https://gist.github.com/wenLiangcan/8764887

    class test:
    def __init__(self):
    self.a = 1
    @classmethod
    def foo(cls, p, flag):
    pass

    def foo(self, p):
    print(self.a)


    可是 test.foo(P, f) 却会报错,显示调用了只有两个参数的 foo
    如果用两个 flag 显然又太笨拙了,请问有什么优雅的写法么?
    第 1 条附言  ·  2014-02-02 20:04:24 +08:00
    17 条回复    1970-01-01 08:00:00 +08:00
    sillyousu
        1
    sillyousu  
       2014-02-02 18:12:02 +08:00   ❤️ 1
    Python 本来就没有重载这一说的。 貌似 普通的method 会把 classmethod 覆盖的。
    sillyousu
        2
    sillyousu  
       2014-02-02 18:18:36 +08:00
    @sillyousu 更正,是写在后面的 method 把前面的覆盖
    ritksm
        3
    ritksm  
       2014-02-02 18:20:46 +08:00   ❤️ 1
    我想知道这样写的实际意义在哪里。为什么会有一个class method和instance method重名,能举个不是foobar的例子么。。

    再说了明明不能重载的嘛,方法重载的意义在于对于静态类型的语言,可以区别不同的方法,但是对于Python直接*args **kwargs不就可以了么,然后在方法逻辑里判断
    ritksm
        4
    ritksm  
       2014-02-02 18:21:34 +08:00
    raquelken
        5
    raquelken  
       2014-02-02 18:22:12 +08:00   ❤️ 1
    raquelken
        6
    raquelken  
       2014-02-02 18:23:05 +08:00
    raquelken
        7
    raquelken  
       2014-02-02 18:24:39 +08:00
    raquelken
        8
    raquelken  
       2014-02-02 18:32:53 +08:00
    raquelken
        9
    raquelken  
       2014-02-02 18:34:13 +08:00
    S**t, 我放弃了

    class test:
    def __init__(self):
    self.a = 1
    self.foo = self._foo

    @classmethod
    def foo(cls, p, flag):
    pass

    def _foo(self, p):
    print(self.a)
    yangff
        10
    yangff  
       2014-02-02 19:18:27 +08:00   ❤️ 1
    yangff
        11
    yangff  
       2014-02-02 19:19:46 +08:00
    orzfly
        12
    orzfly  
       2014-02-02 19:27:06 +08:00   ❤️ 1
    wenLiangcan
        13
    wenLiangcan  
    OP
       2014-02-02 19:58:02 +08:00
    @ritksm 我想写一个豆瓣电台 api 算是 wraper 的类,额,当作练习而已啦。。有些操作可以不登录进行,所以我想登录的话就传入登录信息获得一个实例,不登录就通过 classmethod 操作。当然,也可以用 foo 和 foo_logined 这样区分,可是觉得统一命名比较好看吧。。。。
    wenLiangcan
        14
    wenLiangcan  
    OP
       2014-02-02 19:59:58 +08:00
    @raquelken 原来还可以这样!
    ritksm
        15
    ritksm  
       2014-02-02 20:33:24 +08:00
    感觉应该那么写?然后全部生成一个实例,用内部逻辑去判断是不是登录了。。

    http://gist.github.com/8767690

    而且就算变成了class method,其实也是可以instance.foo_class_method()的...参见 http://docs.python.org/2/library/functions.html#classmethod 感觉LZ是不是和staticmethod搞混了...

    感觉class method基本上都是用来做helper或者工厂方法的...比如上面那个gist的第二个例子
    ritksm
        16
    ritksm  
       2014-02-02 20:35:58 +08:00
    居然。。。贴http地址的gist就被unsafe script了。。。

    来个直接链接吧 https://gist.github.com/ritksm/8767690
    wenLiangcan
        17
    wenLiangcan  
    OP
       2014-02-02 21:00:52 +08:00
    @ritksm 恩,你这样也可以,我就是一直执着于用类和实例这样区分了。。。

    关于 static method,因为那些方法还会访问到一些类中共享的数据,所以觉得 class method 会比较方便
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2284 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 15:59 · PVG 23:59 · LAX 07:59 · JFK 10:59
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.