我在代码中遇到了python中的未绑定方法错误
class Sample(object):
'''This class defines various methods related to the sample'''
def drawSample(samplesize,List):
sample=random.sample(List,samplesize)
return sample
Choices=range(100)
print Sample.drawSample(5,Choices)
Run Code Online (Sandbox Code Playgroud)
在这里阅读了很多有用的帖子之后,我想到了如何在上面添加@staticmethod以使代码正常工作.我是python新手.有人可以解释为什么人们想要定义静态方法吗?或者,为什么并非所有方法都定义为静态方法?
zan*_*etu 164
有关详细说明,请参阅此文章.
TL; DR
1.它消除了self论证的使用.
2.它减少了内存使用量,因为Python不必为每个被通知的对象实例化绑定方法:
>>>RandomClass().regular_method is RandomClass().regular_method
False
>>>RandomClass().static_method is RandomClass().static_method
True
>>>RandomClass.static_method is RandomClass().static_method
True
Run Code Online (Sandbox Code Playgroud)
3.它提高了代码的可读性,表明该方法不依赖于对象本身的状态.
4.它允许方法覆盖,如果方法是在模块级定义的(即在类外),则子类将无法覆盖该方法.
Odd*_*ing 102
静态方法的使用有限,因为它们无法访问类实例的属性(就像常规方法那样),并且它们无法访问类本身的属性(就像类方法一样) ).
因此它们对日常方法没有用.
但是,它们可以用于将一些实用程序功能与类组合在一起 - 例如从一种类型到另一种类型的简单转换 - 除了提供的参数之外不需要访问任何信息(并且可能是模块的全局属性). )
它们可以被放在课堂之外,但是将它们分组到课堂中可能是有意义的,它们只适用于那里.
您还可以通过实例或类引用该方法,而不是模块名称,这可以帮助读者了解该方法的相关实例.
Vic*_*ler 19
这不是你的实际问题,但是因为你说你是一个蟒蛇新手也许它会有所帮助,而且没有其他人能够明确地说出来.
我永远不会通过使该方法成为静态方法来修复上述代码.我要么抛弃了这个类,只是写了一个函数:
def drawSample(samplesize,List):
sample=random.sample(List,samplesize)
return sample
Choices=range(100)
print drawSample(5,Choices)
Run Code Online (Sandbox Code Playgroud)
如果你有许多相关的功能,你可以将它们分组在一个模块中 - 即,将它们全部放在同一个文件中,例如名为sample.py; 然后
import sample
Choices=range(100)
print sample.drawSample(5,Choices)
Run Code Online (Sandbox Code Playgroud)
或者我会在类中添加一个init方法并创建一个具有有用方法的实例:
class Sample(object):
'''This class defines various methods related to the sample'''
def __init__(self, thelist):
self.list = thelist
def draw_sample(self, samplesize):
sample=random.sample(self.list,samplesize)
return sample
choices=Sample(range(100))
print choices.draw_sample(5)
Run Code Online (Sandbox Code Playgroud)
(我还更改了上例中的案例约定,以匹配PEP 8推荐的样式.)
Python的一个优点是它不会强迫你为所有东西使用类.只有当存在应该与方法关联的数据或状态时,才可以使用它们,这是类的用途.否则你可以使用函数,这是函数的用途.
Pra*_*are 16
为什么要定义静态方法?
假设我们有一个class叫做的Math话
没有人会希望创建的对象class Math
,然后调用类似的方法ceil,并floor与fabs它.
所以我们制作它们static.
例如做
>> Math.floor(3.14)
Run Code Online (Sandbox Code Playgroud)
好多了
>> mymath = Math()
>> mymath.floor(3.14)
Run Code Online (Sandbox Code Playgroud)
所以它们在某种程度上是有用的.您无需创建类的实例即可使用它们.
为什么并非所有方法都定义为静态方法?
他们无权访问实例变量.
class Foo(object):
def __init__(self):
self.bar = 'bar'
def too(self):
print self.bar
@staticmethod
def foo():
print self.bar
Foo().too() # works
Foo.foo() # doesn't work
Run Code Online (Sandbox Code Playgroud)
这就是为什么我们不将所有方法都设为静态的原因.
Mat*_*son 12
当您从对象实例调用函数对象时,它将变为"绑定方法"并获取实例对象本身作为第一个参数传入.
当您classmethod在对象实例上调用对象(包装函数对象)时,实例对象的类将作为第一个参数传入.
当您调用一个staticmethod对象(包装一个函数对象)时,不会使用隐式的第一个参数.
class Foo(object):
def bar(*args):
print args
@classmethod
def baaz(*args):
print args
@staticmethod
def quux(*args):
print args
>>> foo = Foo()
>>> Foo.bar(1,2,3)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unbound method bar() must be called with Foo instance as first argument (got int instance instead)
>>> Foo.baaz(1,2,3)
(<class 'Foo'>, 1, 2, 3)
>>> Foo.quux(1,2,3)
(1, 2, 3)
>>> foo.bar(1,2,3)
(<Foo object at 0x1004a4510>, 1, 2, 3)
>>> foo.baaz(1,2,3)
(<class 'Foo'>, 1, 2, 3)
>>> foo.quux(1,2,3)
(1, 2, 3)
Run Code Online (Sandbox Code Playgroud)
Joo*_*eey 10
一个替代方案staticmethod是:classmethod,instancemethod,和function。如果您不知道这些是什么,请向下滚动到最后一部分。如果 astaticmethod比这些替代方案中的任何一个都好,则取决于它的编写目的。
staticmethod比 aclassmethod或 好instancemethod。这样很明显(从@staticmethod装饰器)类和实例的状态没有被读取或修改。但是,使用 afunction会使这种区别更加清晰(请参阅缺点)。staticmethodaclassmethod或的调用签名相同instancemethod,即<instance>.<method>(<arguments>)。因此,如果稍后或在派生类中需要,可以很容易地将其替换为三者之一。你不能用一个简单的function.staticmethod可以用来代替function,以明确其主观上属于一类,并防止命名空间冲突。staticmethod与 aclassmethod或的调用签名相同instancemethod。这掩盖了实际上staticmethod不读取或修改任何对象信息的事实。这使得代码更难阅读。为什么不直接使用function?staticmethod如果您需要从定义它的类/实例外部调用它,则很难重用A。如果有任何重复使用的潜力,afunction是更好的选择。staticmethod应用较少,所以人们阅读的代码,其中包括一个可能需要一点时间来阅读。为了讨论 的优点staticmethod,我们需要知道替代方案是什么以及它们之间有何不同。
staticmethod属于一类,但不能访问或修改任何实例或类的信息。它有以下三种替代方案:
classmethod访问调用者的类。instancemethod访问调用者的实例和它的类。function无关带班。它在功能上最接近staticmethod.这是代码中的样子:
# function
# has nothing to do with a class
def make_cat_noise(asker_name):
print('Hi %s, mieets mieets!' % asker_name)
# Yey, we can make cat noises before we've even defined what a cat is!
make_cat_noise('JOey') # just a function
class Cat:
number_of_legs = 4
# special instance method __init__
def __init__(self, name):
self.name = name
# instancemethod
# the instance (e.g. Cat('Kitty')) is passed as the first method argument
def tell_me_about_this_animal(self, asker_name):
print('Hi %s, This cat has %d legs and is called %s'
% (asker_name, self.number_of_legs, self.name))
# classmethod
# the class (e.g. Cat) is passed as the first method argument
# by convention we call that argument cls
@classmethod
def tell_me_about_cats(cls, asker_name):
print("Hi %s, cats have %d legs."
% (asker_name, cls.number_of_legs))
# cls.name # AttributeError because only the instance has .name
# self.name # NameError because self isn't defined in this namespace
# staticmethod
# no information about the class or the instance is passed to the method
@staticmethod
def make_noise(asker_name):
print('Hi %s, meooow!' % asker_name)
# class and instance are not accessible from here
# one more time for fun!
make_cat_noise('JOey') # just a function
# We just need the class to call a classmethod or staticmethod:
Cat.make_noise('JOey') # staticmethod
Cat.tell_me_about_cats('JOey') # classmethod
# Cat.tell_me_about_this_animal('JOey') # instancemethod -> TypeError
# With an instance we can use instancemethod, classmethod or staticmethod
mycat = Cat('Kitty') # mycat is an instance of the class Cat
mycat.make_noise('JOey') # staticmethod
mycat.tell_me_about_cats('JOey') # classmethod
mycat.tell_me_about_this_animal('JOey') # instancemethod
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
33192 次 |
| 最近记录: |