我可以定义一个可以直接在类实例上调用的静态方法吗?例如。,
MyClass.the_static_method()
我可以定义一个可以直接在类实例上调用的静态方法吗?例如。,
MyClass.the_static_method()
当前回答
您实际上不需要使用@staticmethoddecorator。只需声明一个方法(不需要self参数)并从类中调用它。装饰器仅在您希望能够从实例调用它时才存在(这不是您想要做的)
大多数情况下,你只是使用函数。。。
其他回答
除了静态方法对象行为的特殊性之外,在组织模块级代码时,还可以使用它们来实现某种美感。
# garden.py
def trim(a):
pass
def strip(a):
pass
def bunch(a, b):
pass
def _foo(foo):
pass
class powertools(object):
"""
Provides much regarded gardening power tools.
"""
@staticmethod
def answer_to_the_ultimate_question_of_life_the_universe_and_everything():
return 42
@staticmethod
def random():
return 13
@staticmethod
def promise():
return True
def _bar(baz, quux):
pass
class _Dice(object):
pass
class _6d(_Dice):
pass
class _12d(_Dice):
pass
class _Smarter:
pass
class _MagicalPonies:
pass
class _Samurai:
pass
class Foo(_6d, _Samurai):
pass
class Bar(_12d, _Smarter, _MagicalPonies):
pass
...
# tests.py
import unittest
import garden
class GardenTests(unittest.TestCase):
pass
class PowertoolsTests(unittest.TestCase):
pass
class FooTests(unittest.TestCase):
pass
class BarTests(unittest.TestCase):
pass
...
# interactive.py
from garden import trim, bunch, Foo
f = trim(Foo())
bunch(f, Foo())
...
# my_garden.py
import garden
from garden import powertools
class _Cowboy(garden._Samurai):
def hit():
return powertools.promise() and powertools.random() or 0
class Foo(_Cowboy, garden.Foo):
pass
现在,它变得更加直观和自我记录,在这种情况下,某些组件将被使用,它非常适合于命名不同的测试用例,并为纯粹主义者提供了一种直接的方法来说明测试模块如何映射到实际的测试模块。
我经常发现将这种方法应用于组织项目的实用程序代码是可行的。通常情况下,人们会立即匆忙创建一个utils包,最终得到9个模块,其中一个模块有120个LOC,其余模块最多有20个LOC。我宁愿从这个开始,将其转换为一个包,并只为真正值得拥有它们的野兽创建模块:
# utils.py
class socket(object):
@staticmethod
def check_if_port_available(port):
pass
@staticmethod
def get_free_port(port)
pass
class image(object):
@staticmethod
def to_rgb(image):
pass
@staticmethod
def to_cmyk(image):
pass
我不时遇到这个问题。我喜欢的用例和示例是:
jeffs@jeffs-desktop:/home/jeffs $ python36
Python 3.6.1 (default, Sep 7 2017, 16:36:03)
[GCC 6.3.0 20170406] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import cmath
>>> print(cmath.sqrt(-4))
2j
>>>
>>> dir(cmath)
['__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'acos', 'acosh', 'asin', 'asinh', 'atan', 'atanh', 'cos', 'cosh', 'e', 'exp', 'inf', 'infj', 'isclose', 'isfinite', 'isinf', 'isnan', 'log', 'log10', 'nan', 'nanj', 'phase', 'pi', 'polar', 'rect', 'sin', 'sinh', 'sqrt', 'tan', 'tanh', 'tau']
>>>
创建cmath类的对象是没有意义的,因为cmath对象中没有状态。然而,cmath是一组方法的集合,它们都以某种方式相关。在我上面的例子中,cmath中的所有函数都以某种方式作用于复数。
您可以使用@staticmethoddecorator定义静态方法,如下所示。我在Python中对@classmethod vs@staticmethod的回答中详细解释了@staticmmethod decorator和@classmethoddecorator,并在Python中什么是“实例方法”的回答中解释了实例方法:
class Person:
@staticmethod # Here
def test():
print("Test")
您实际上不需要使用@staticmethoddecorator。只需声明一个方法(不需要self参数)并从类中调用它。装饰器仅在您希望能够从实例调用它时才存在(这不是您想要做的)
大多数情况下,你只是使用函数。。。
是的,使用静态方法装饰器:
class MyClass(object):
@staticmethod
def the_static_method(x):
print(x)
MyClass.the_static_method(2) # outputs 2
注意,一些代码可能使用旧的定义静态方法的方法,使用staticmethod作为函数而不是修饰符。仅当您必须支持Python的早期版本(2.2和2.3)时,才应使用此选项:
class MyClass(object):
def the_static_method(x):
print(x)
the_static_method = staticmethod(the_static_method)
MyClass.the_static_method(2) # outputs 2
这与第一个示例(使用@staticmethod)完全相同,只是没有使用漂亮的decorator语法。
最后,谨慎使用静态方法!在Python中很少有静态方法是必需的,而且我已经多次看到它们被使用,而单独的“顶级”函数会更清晰。
以下是文件中的逐字内容:
静态方法不接收隐式第一个参数。要声明静态方法,请使用以下习惯用法:C类:@静态方法定义f(arg1,arg2,…):。。。@staticmethod表单是一个函数装饰器–有关详细信息,请参阅函数定义中的函数定义描述。它既可以在类(如C.f())上调用,也可以在实例(如C().f())中调用。除了它的类之外,该实例将被忽略。Python中的静态方法与Java或C++中的方法类似。有关更高级的概念,请参阅classmethod()。有关静态方法的更多信息,请参阅标准类型层次结构中有关标准类型层次的文档。2.2版中的新增功能。在版本2.4中进行了更改:添加了函数修饰符语法。