Python中的静态方法?
是否有可能在Python中有静态方法,所以我可以在不初始化类的情况下调用它们,如:
ClassName.StaticMethod ( )
是的,使用staticmethod装饰器
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
),只是没有使用好的装饰器语法
最后,谨慎使用staticmethod()
! 有很少的情况需要在Python中使用静态方法,并且在单独的“顶层”函数更清晰的情况下,我已经看到它们被多次使用。
以下是从文档逐字:
静态方法不会收到隐式的第一个参数。 要声明一个静态方法,使用这个习惯用法:
class C:
@staticmethod
def f(arg1, arg2, ...): ...
@staticmethod表单是一个函数装饰器 - 有关详细信息,请参阅函数定义中函数定义的描述。
它可以在类(如Cf()
)或实例(如C().f()
)上调用。 该实例被忽略,除了它的类。
Python中的静态方法类似于Java或C ++中的方法。 有关更高级的概念,请参见classmethod()
。
有关静态方法的更多信息,请参阅标准类型层次结构中标准类型层次结构的文档。
2.2版本中的新功能。
在版本2.4中更改:添加了函数装饰器语法。
我认为史蒂文其实是对的。 为了回答最初的问题,为了建立一个类方法,简单地假定第一个参数不会是一个调用实例,然后确保只调用该方法。
(请注意,这个答案是指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是数字时,n将代表Dog实例(即rex)。
这是装饰进入的地方:如果我们在“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装饰器:
>>> class C:
... @staticmethod
... def hello():
... print "Hello World"
...
>>> C.hello()
Hello World
链接地址: http://www.djcxy.com/p/1613.html