我可以定义一个可以直接在类实例上调用的静态方法吗?例如。,
MyClass.the_static_method()
我可以定义一个可以直接在类实例上调用的静态方法吗?例如。,
MyClass.the_static_method()
当前回答
我不时遇到这个问题。我喜欢的用例和示例是:
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:
>>> class C:
... @staticmethod
... def hello():
... print "Hello World"
...
>>> C.hello()
Hello World
我认为史蒂文实际上是对的。为了回答最初的问题,那么,为了设置一个类方法,只需假设第一个参数不是一个调用实例,然后确保只从类调用该方法。
(注意,这个答案指的是Python 3.x。在Python 2.x中,调用类本身的方法会得到一个TypeError。)
例如:
class Dog:
count = 0 # this is a class variable
dogs = [] # this is a class variable
def __init__(self, name):
self.name = name #self.name is an instance variable
Dog.count += 1
Dog.dogs.append(name)
def bark(self, n): # this is an instance method
print("{} says: {}".format(self.name, "woof! " * n))
def rollCall(n): #this is implicitly a class method (see comments below)
print("There are {} dogs.".format(Dog.count))
if n >= len(Dog.dogs) or n < 0:
print("They are:")
for dog in Dog.dogs:
print(" {}".format(dog))
else:
print("The dog indexed at {} is {}.".format(n, Dog.dogs[n]))
fido = Dog("Fido")
fido.bark(3)
Dog.rollCall(-1)
rex = Dog("Rex")
Dog.rollCall(0)
在这段代码中,“rollCall”方法假设第一个参数不是实例(如果它是由实例而不是类调用的话)。只要从类而不是实例调用“rollCall”,代码就会正常工作。如果我们尝试从实例调用“rollCall”,例如:
rex.rollCall(-1)
然而,它将导致引发异常,因为它将发送两个参数:自身和-1,而“rollCall”仅定义为接受一个参数。
顺便说一句,rex.rollCall()将发送正确数量的参数,但也会引发异常,因为现在n将表示Dog实例(即rex),而函数期望n是数字。
这就是装饰的由来:如果我们在“rollCall”方法前面加上
@staticmethod
然后,通过显式声明该方法是静态的,我们甚至可以从实例调用它。现在
rex.rollCall(-1)
会起作用。然后,在方法定义之前插入@staticmethod会阻止实例将自身作为参数发送。
您可以通过使用或不使用注释掉的@staticmethod行尝试以下代码来验证这一点。
class Dog:
count = 0 # this is a class variable
dogs = [] # this is a class variable
def __init__(self, name):
self.name = name #self.name is an instance variable
Dog.count += 1
Dog.dogs.append(name)
def bark(self, n): # this is an instance method
print("{} says: {}".format(self.name, "woof! " * n))
@staticmethod
def rollCall(n):
print("There are {} dogs.".format(Dog.count))
if n >= len(Dog.dogs) or n < 0:
print("They are:")
for dog in Dog.dogs:
print(" {}".format(dog))
else:
print("The dog indexed at {} is {}.".format(n, Dog.dogs[n]))
fido = Dog("Fido")
fido.bark(3)
Dog.rollCall(-1)
rex = Dog("Rex")
Dog.rollCall(0)
rex.rollCall(-1)
因此,静态方法是可以在不创建类对象的情况下调用的方法。例如:-
@staticmethod
def add(a, b):
return a + b
b = A.add(12,12)
print b
在上面的示例中,add是由类名A而不是对象名调用的。
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
您实际上不需要使用@staticmethoddecorator。只需声明一个方法(不需要self参数)并从类中调用它。装饰器仅在您希望能够从实例调用它时才存在(这不是您想要做的)
大多数情况下,你只是使用函数。。。