我正在创建一个类,希望在该类的方法中调用用户定义的函数。我还想在类定义中定义函数。但是,当我调用该类时,会收到错误消息name *whatever function* is not defined
。
例如,如下所示:
class ExampleClass():
def __init__(self, number):
self.number = number
def plus_2_times_4(x):
return(4*(x + 2))
def arithmetic(self):
return(plus_2_times_4(self.number))
但是当我打电话时:
instance = ExampleClass(number = 4)
instance.arithmetic()
我收到错误消息。
因此,基本上我想在一个步骤(def plus_2_times_4
)中定义函数,并在另一步骤(d ef arithmetic...
)中定义方法时使用该函数。这可能吗?
非常感谢!
答案 0 :(得分:4)
用plus_2_times_4
定义并调用self
,即:
class ExampleClass():
def __init__(self, number):
self.number = number
def plus_2_times_4(self,x):
return(4*(x + 2))
def arithmetic(self):
return(self.plus_2_times_4(self.number))
这将起作用。
答案 1 :(得分:2)
使用ExampleClass.plus_2_times_4
调用方法:
class ExampleClass():
def __init__(self, number):
self.number = number
def plus_2_times_4(x):
return(4*(x + 2))
def arithmetic(self):
return(ExampleClass.plus_2_times_4(self.number))
或者,使用@staticmethod
装饰器并使用常规方法调用语法来调用该方法:
class ExampleClass():
def __init__(self, number):
self.number = number
@staticmethod
def plus_2_times_4(x):
return(4*(x + 2))
def arithmetic(self):
return(self.plus_2_times_4(self.number))
@staticmethod
装饰器确保self
不会像通常用于方法那样隐式传递。
答案 2 :(得分:1)
查看您的plus_2_times_4
和arithmetic
的定义。 Python无法告诉您要它们中的一个是局部函数,而另一个是方法。它们的定义方式完全相同。
实际上,他们俩都是。在Python中,您在class
语句主体中放置的任何内容都是在该类定义发生时是局部的,并且稍后会变为类属性。
如果您希望以后能够以plus_2_times_4
的形式调用该函数,则不需要这样做。您只想在类定义之外声明一个全局函数。这确实确实像您在这里想要的。该函数与该类没有任何固有的联系;它只需要一个数字,并对该数字进行填充,而无需考虑与您的班级有关的任何事情。
或者,如果您不想“污染全局名称空间”,则可以将其定义为arithmetic
中的局部函数。然后arithmetic
可以调用它,而其他任何人都不能。
另一方面,如果您希望将其用作方法,则必须使其可用作方法。普通实例方法必须使用self
作为额外的第一个参数,即使它不会对self
做任何事情。 (尽管对self
不执行任何操作通常表明您想要一个全局函数,而不是方法,但这不是非法的或其他任何事情。)而且必须在实例上调用它,例如self.plus_2_times_4(…)
。
您可以通过添加@staticmethod
装饰器将其声明为静态方法。然后,您无需添加无用的self
参数。但是您仍然需要在实例或类上调用它,因为它仍然是类的属性,而不是全局名称。 (如果您想让子类重写它,也可以使用@classmethod
,但在这里似乎不太可能。)
如果您真的只想捕获函数值,以便无需遍历类就可以调用它怎么办?好吧,您可以将其设置为参数的默认值,如下所示:
def arithmetic(self, *, _func=plus_2_times_4):
return func(self.value)
默认值是在函数定义时(即,仍在定义类时)捕获的,因此函数仍在本地,可以在此处捕获。但是,如果这看起来很怪异和丑陋,则有充分的理由-您通常不需要这样做。对于读者而言,该函数看起来仍然是一种不正确的方法,而不是arithmetic
所需要的一次性函数。它甚至以班级成员的身份结束,但不能正常调用。这全都是误导。在极少数情况下,您需要使用此名称,您可能想给它一个_private
的名称,并在使用后为其命名del
。