在Python中调用类方法中的方法

时间:2015-01-09 04:52:35

标签: python

我发现当从类的方法中调用方法时,我不需要将任何变量传递给方法。相反,它只是在调用方法时继承该方法的属性。

class Person(object):
    def method1(self):
        print(self.attr1)

    def method2(self):
        self.attr1 = 'attr1'
        self.method1()

这对我有用。但是,我的第一次直观尝试包括以下非功能性代码。

class Person(object):
    def method1(self, attr1):
        print(self.attr1)

    def method2(self):
        self.method1('attr1')

即使我找到了问题的解决方案,我也非常有兴趣了解这一问题背后的基础。

编辑:我试图理解的例子是:

class Converter(object):

    def split(self, x):
        self.a, self.b, self.z, self.c = self.x.split(' ')
        self.z = None
        self.a = int(self.a)

    def converter(self, unit, example):
        self.x = ''
        while self.x != 'exit':
            self.x = input("Type '50 %s' or similar, or type 'units' to view valid units; type 'exit' to return to the main menu: " % (self.example))
            if self.x == 'exit':
                break
            elif self.x == 'units':
                print(list(self.units.keys()))
            else:
                self.split(self.x)
                print(self.a / self.units[self.b] * self.units[self.c], self.c)

    def volume(self):
        self.units = { 'L': 1,
                       'mL': 1000,
                       'q': 1.05699,
                       'p': 2.11338,
                       'gal': 3.78541,
                       'oz': 33.814,
                       'ccm': 1000,
                       'cin': 61.024
                        }

        self.example = 'L to q'
        self.converter()

我不明白为什么这不起作用:

class Converter(object):

    def split(self, x):
        self.a, self.b, self.z, self.c = self.x.split(' ')
        self.z = None
        self.a = int(self.a)

    def converter(self):
        self.x = ''
        while self.x != 'exit':
            self.x = input("Type '50 %s' or similar, or type 'units' to view valid units; type 'exit' to return to the main menu: " % (self.example))
            if self.x == 'exit':
                break
            elif self.x == 'units':
                print(list(self.units.keys()))
            else:
                self.split(self.x)
                print(self.a / self.units[self.b] * self.units[self.c], self.c)

    def volume(self):
        self.units = { 'L': 1,
                       'mL': 1000,
                       'q': 1.05699,
                       'p': 2.11338,
                       'gal': 3.78541,
                       'oz': 33.814,
                       'ccm': 1000,
                       'cin': 61.024
                        }

        self.converter({'L':2}, 'L to q')

EDIT2:好的,我想我现在明白了。这些属性被附加到实例对象,我只是没有将传递给下一个函数的属性分配给实例对象。

3 个答案:

答案 0 :(得分:2)

在第二个(也就是非功能性)代码中,您尝试从self.attr1调用method1,但Person对象中不存在此类属性。
method1如果说print(attr1),那么attr1就可以正常工作了,其中method1是作为method1的第二个参数发送的变量

顺便说一下,如果有人在调用method2之前尝试在对象上调用attr1,则新代码会抛出错误。这是因为在method2运行之前,Person对象没有self.attr1属性。

当你对不同的东西有相似的名字/字符串值时,理解发生了什么变得非常困难。我建议对attr1"attr1"和{{1}}使用不同的名称/值,为什么原始代码不起作用会更加明显。

答案 1 :(得分:2)

您表达问题的方式表明您误解了属性的工作原理。属性属于对象(类的实例),而不属于方法。如果你有这样的方法:

def method2(self):
    self.attr1 = 'attr1'
    self.method1()

self指的是您正在调用该方法的实例。例如,如果您执行bob = Person()然后bob.method2()self将与bob成为同一个对象。执行self.attr1 = 'attr1'时,可以在该对象上设置属性。如果您再调用method1,则可以访问该对象的所有属性。你没有放在那里的任何属性都没有。

简单地说,如果你从未做过self.attr1 = whatever,那么尝试获取self.attr1的值将永远不会有效。在第二个示例中,您永远不会self.attr1 = ...,因此无法获得attr1属性。

我同意zehnpaard您使用相同的标签attr1作为属性名称(self.attr1),本地变量名称(attr1)和字符串值来混淆事物('attr1')。将所有这些改变为不同的东西,你就会开始看到它们的工作方式不同。

答案 2 :(得分:1)

在此:

class Person(object):
    def method1(self):
        print(self.attr1)

    def method2(self):
        self.attr1 = 'attr1'
        self.method1()

您已将self传递给method1函数,该函数代表Person类的实例。之后,您可以调用attr1,因为您已在method1命名空间中拥有实例。

这就是为什么你不必再次将字符串'attr1'传递给method1进行打印。