我可以定义一个可以直接在类实例上调用的静态方法吗?例如。,

MyClass.the_static_method()

当前回答

Python静态方法可以通过两种方式创建。

使用静态方法()类算术:def-add(x,y):返回x+y#创建添加静态方法Arithmetic.add=静态方法(算术.add)print('结果:',算术.add(15,10))

输出:

结果:25

使用@staticmethod类算术:#创建添加静态方法@静态方法def-add(x,y):返回x+yprint('结果:',算术.add(15,10))

输出:

结果:25

其他回答

总结其他人的回答并补充,在python中声明静态方法或变量有很多种方法。

使用staticmethod()作为装饰符:可以简单地在声明的方法(函数)上方放置一个修饰符,使其成为静态方法。例如。

class Calculator:
    @staticmethod
    def multiply(n1, n2, *args):
        Res = 1
        for num in args: Res *= num
        return n1 * n2 * Res

print(Calculator.multiply(1, 2, 3, 4))              # 24

使用staticmethod()作为参数函数:此方法可以接收函数类型的参数,并返回传递函数的静态版本。例如。

class Calculator:
    def add(n1, n2, *args):
        return n1 + n2 + sum(args)

Calculator.add = staticmethod(Calculator.add)
print(Calculator.add(1, 2, 3, 4))                   # 10

使用classmethod()作为装饰符:@classmethod对函数的影响与@staticmethod类似,但是这一次,需要在函数中接受一个额外的参数(类似于实例变量的self参数)。例如。

class Calculator:
    num = 0
    def __init__(self, digits) -> None:
        Calculator.num = int(''.join(digits))

    @classmethod
    def get_digits(cls, num):
        digits = list(str(num))
        calc = cls(digits)
        return calc.num

print(Calculator.get_digits(314159))                # 314159

使用classmethod()作为参数函数:@classmethod也可以用作参数函数,以防不想修改类定义。例如。

class Calculator:
    def divide(cls, n1, n2, *args):
        Res = 1
        for num in args: Res *= num
        return n1 / n2 / Res

Calculator.divide = classmethod(Calculator.divide)

print(Calculator.divide(15, 3, 5))                  # 1.0

直接申报在所有其他方法外部但在类内部声明的方法/变量自动是静态的。

class Calculator:   
    def subtract(n1, n2, *args):
        return n1 - n2 - sum(args)

print(Calculator.subtract(10, 2, 3, 4))             # 1

整个计划

class Calculator:
    num = 0
    def __init__(self, digits) -> None:
        Calculator.num = int(''.join(digits))
    
    
    @staticmethod
    def multiply(n1, n2, *args):
        Res = 1
        for num in args: Res *= num
        return n1 * n2 * Res


    def add(n1, n2, *args):
        return n1 + n2 + sum(args)
    

    @classmethod
    def get_digits(cls, num):
        digits = list(str(num))
        calc = cls(digits)
        return calc.num


    def divide(cls, n1, n2, *args):
        Res = 1
        for num in args: Res *= num
        return n1 / n2 / Res


    def subtract(n1, n2, *args):
        return n1 - n2 - sum(args)
    



Calculator.add = staticmethod(Calculator.add)
Calculator.divide = classmethod(Calculator.divide)

print(Calculator.multiply(1, 2, 3, 4))              # 24
print(Calculator.add(1, 2, 3, 4))                   # 10
print(Calculator.get_digits(314159))                # 314159
print(Calculator.divide(15, 3, 5))                  # 1.0
print(Calculator.subtract(10, 2, 3, 4))             # 1

有关掌握Python中的OOP,请参阅Python文档。

Python中的静态方法?是否可以在Python中使用静态方法,以便我可以调用它们而不初始化类,例如:ClassName.StaticMethod()

是的,静态方法可以这样创建(虽然使用下划线而不是CamelCase来创建方法有点像Python):

class ClassName(object):

    @staticmethod
    def static_method(kwarg1=None):
        '''return a value that is a function of kwarg1'''

上面使用了decorator语法。此语法等效于

class ClassName(object):

    def static_method(kwarg1=None):
        '''return a value that is a function of kwarg1'''

    static_method = staticmethod(static_method)

这可以按照您所描述的方式使用:

ClassName.static_method()

静态方法的一个内置示例是Python 3中的str.maketrans(),它是Python 2中字符串模块中的一个函数。


正如您所描述的,另一个可以使用的选项是classmethod,不同之处在于classmethod将类作为隐式第一个参数,如果是子类,则将子类作为隐的第一个参数。

class ClassName(object):

    @classmethod
    def class_method(cls, kwarg1=None):
        '''return a value that is a function of the class and kwarg1'''

请注意,cls不是第一个参数的必需名称,但如果您使用其他名称,大多数有经验的Python程序员会认为它做得很糟糕。

这些通常用作替代构造函数。

new_instance = ClassName.class_method()

内置示例是dict.fromkeys():

new_dict = dict.fromkeys(['key1', 'key2'])

您实际上不需要使用@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中进行了更改:添加了函数修饰符语法。

除了静态方法对象行为的特殊性之外,在组织模块级代码时,还可以使用它们来实现某种美感。

# 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