繁体   English   中英

python - 我应该使用静态方法还是顶级函数

[英]python - should I use static methods or top-level functions

我来自Java背景,我是python的新手。 我有几个脚本共享一些与读取和写入文件相关的应用程序独有的辅助函数。 一些与阅读相关的功能,一些与写作相关。 在搜索正确的方法时,我看到了这一点: Python中的静态方法?

他在回答中提到:

最后,谨慎使用static方法! 在Python中很少需要使用静态方法,并且我已经看到它们多次使用,其中单独的“顶级”函数会更清晰。

我不太了解顶级函数,我不确定给出这个更好的简单示例:1)为具有静态读取器函数的读者创建一个类,为编写者创建相同的类或2)声明这些帮助器作为全球功能,为什么?

编辑:关于这个主题的真正好文章我刚刚找到http://tomayko.com/writings/the-static-method-thing

在Java中,(IMHO错误的)想法是在任何地方使用类,甚至只是将不共享任何状态的静态函数组合在一起(因此这些类永远不会被实例化)。

Python在这里要求不同; 如果您的函数没有某些共享状态1 (因此在Java中通常是static函数)并且与“真实”类(=实际实例化的类)没有紧密关联,您​​只需使用里面的自由函数一个模块。

这背后的原因是只有当你真正想要实例化它时才需要一个类,因此将一个类作为几个不需要共享特定于实例的状态的函数的容器是没用的。

其实,你可以觉得有点模块作为的static类-即功能(=静态方法),模块变量(=静态字段)和类型的容器。

Python中的好处是拥有顶级函数不会产生全局命名空间污染问题,因为在Python中,顶层函数/ objects / ...仍然是模块范围的。 因此,您仍然可以按模块对函数进行分组,而不必使用不必要的class -tax。


  1. 实际上,它们可以以模块级变量的形式存在一些共享状态(因此,单例); 再次,类比模块 - 静态类似乎成立。

来自Python的Zen( import this ):

Namespaces are one honking great idea -- let's do more of those!

在像Java这样的语言中创建静态方法的主要原因之一是确保这些方法不会污染全局命名空间。 (尽管Java通过完全禁止“包级”函数来强制执行其自己的命名空间约定!)在Python中,所有“顶级”函数都自动放置在包含这些函数的模块的命名空间内,因此不存在污染全局的危险命名空间这样。

换句话说,与许多其他语言一样,Python可以通过几种不同的方式创建命名空间。 在这种情况下,当模块提供相同的命名空间目的而没有与定义类相关联的混乱(或认知负载)时,几乎不需要创建仅包含静态方法的类。

如果函数与类相关,则将其设为静态方法。 例如:

class DBobject():
    name = StringProperty()

    @staticmethod
    def get_by_name(name):
        return db.select('select * from DBobject where name = "%s"' % name)

python = DBobject.get_by_name('python')

也就是说,该方法与DBobject类完全相关,因此它应该是一个静态方法。

它是命名空间污染的问题。 如果你有一个包含多个类的模块和一些只对某个类及其后代有意义的函数,那么将它作为一个静态方法。 可以使用类名或使用类的对象来调用静态方法。

>>> class A(object):
...     @staticmethod
...     def static_1():
...             print 'i am static'
...     def a(self):
...             self.static_1()
...
>>> A.static_1()
i am static
>>> a=A()
>>> a.a()
i am static
>>> a.static_1()
i am static
>>> class B(A):
...     pass
...
>>> b=B()
>>> b.static_1()
i am static
>>>

Python静态方法的另一个方面是,当在实例上调用时,它们在调用它们的变量的类型上是多态的,尽管没有self的实例。

例如:

class BaseClass:
    @staticmethod
    def my_method():
        return 0


class SubclassLeft:
    @staticmethod
    def my_method():
        return "left"


class SubclassRight:
    @staticmethod
    def my_method():
        return "right"


instances = [BaseClass(), SubclassLeft(), SubclassRight()]

for i in instances:
    print(i.my_method())

运行此结果

$ python example.py
0
left
right

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM