我正在尝试使用类来重写一些代码。在某些时候,我想要为对象的每个实例使用一个参数值来分配成员函数的特定定义。
作为其他语言(JavaScript、C++、Haskell、Fortran等)的开发者,我很难理解Python中的一些东西。其中之一就是类方法中“self”的区别。
例如,以下代码显然无法工作:
class fdf:
def f(x):
return 666
class gdg(fdf):
def sq():
return 7*7
hg = gdg()
hf = fdf()
print(hf.f(),hg.f(),hg.sq())
这段代码报错:“sq()接受了0个位置参数,但实际给出了1个”。
我理解的原因是,在执行时,函数被传递了一个指向调用对象(即调用sq的实例)的引用作为第一个参数,然后才是我们定义/调用sq时使用的任何其他参数/参数。所以解决方案很简单:将sq的代码更改为def sq(self):
。实际上,Python教程1似乎建议将对象方法始终定义为带有self
作为第一个参数。这样做可以得到预期的结果666 666 49
,目前为止还不错。
但是,当我尝试像这样实现我的类时:
class Activation:
def nonLinearBipolarStep(self,x,string=None):
if not string: return (-1 if x<0 else 1 )
else: return ('-' if x<0 else '1')
default='bipolar'
activationFunctions = {
'bipolar': nonLinearBipolarStep ,
}
def _getActivation(self,func=default):
return self.activationFunctions.get(func,self.activationFunctions.get(self.default))
def __init__(self,func=None):
if func == None: func=self.default
self.run = self._getActivation(func)
ag = Activation()
print(ag.run(4))
我遇到了错误
nonLinearBipolarStep() missing 1 required positional argument: 'x'
然而,一个解决方法是在不使用参数 self
的情况下定义步进函数,即:
然而,一个解决方法是在不使用参数 self
的情况下定义步进函数,即:
def nonLinearBipolarStep(x,string=None):
然后我得到了预期的行为(至少对于这个琐碎的测试)1
。所以,不仅在这里不需要self
,在这里使用它甚至是不正确的!
但根据上述教程或像这个2或这个3这样的帖子中的答案,我想这段代码不应该工作...或者在某些时候可能会有一些意外后果?确实,如果我在_getActivation
的定义中删除所有对self
的引用,我会得到错误消息_getActivation() takes from 0 to 1 positional arguments but 2 were given
,根据这个规则,我可以理解。
线程“Why is self not used in this method”4对我来说并没有提供一个清晰的答案:上面代码的什么语法细节告诉我不需要self
?例如,那段代码与这个教程示例有什么不同。
class MyClass:
"""A simple example class"""
i = 12345
def f(self):
return 'hello world'
? 实例化这个类的时候可以正常工作,但是如果定义为none,则会抱怨缺少参数(我知道它可以是任何标签)。
这让我怀疑我的代码是否隐藏了一个定时炸弹:是self
被传递为x
的值吗?它按预期工作,所以我会说不是,但是我面临着这个难题。
我想我错过了一些语言的关键思想。我承认我也在努力回答参考3的OP提出的问题。
[^]:在JS中,函数体内只使用this
,函数本身要么被定义为对象的原型成员,要么被定义为实例成员,然后使用...this
正确地分配。
编辑:
线程很长。对于那些正在寻找帮助的人,如果你是新手,请查看选定的解决方案及其评论。但是,如果您已经了解Python中的绑定/非绑定方法,您只需要直接检查如Blckknght的答案所述的描述符的用法。最终,我选择在我的代码中使用__get__
分配到运行中。
@staticmethod
进行工作。 - Willem Van Onsemself
。如果你用@staticmethod
装饰函数,就不需要使用self
。 - Willem Van Onsem