在Python类中定义和调用函数

时间:2018-08-06 15:37:08

标签: python

我正在创建一个类,希望在该类的方法中调用用户定义的函数。我还想在类定义中定义函数。但是,当我调用该类时,会收到错误消息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...)中定义方法时使用该函数。这可能吗?

非常感谢!

3 个答案:

答案 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_4arithmetic的定义。 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