简体   繁体   English

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

[英]Calling methods within a class method in Python

I have found that when calling methods from within a method of a class I do not need to pass any variables to the method. 我发现从类的方法中调用方法时,不需要将任何变量传递给该方法。 Instead it simply inherits the attributes from that method when the method is called. 相反,在调用方法时,它仅从该方法继承属性。

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

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

This works for me. 这对我有用。 However, my first intuitive attempt consisted of the following nonfunctional code. 但是,我的第一个直观尝试是由以下非功能性代码组成。

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

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

Even though I figured out a solution to the problem, I'm very much interested to learn the underpinnings behind this one. 即使我找到了解决问题的方法,但我仍然非常有兴趣了解这一问题的基础。

EDIT: The example I am trying to understand is this: 编辑:我想理解的示例是这样的:

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()

I don't understand why this wouldn't work: 我不明白为什么这行不通:

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: Okay I think I understand now. EDIT2:好的,我想我现在明白了。 The attributes are being attached to the instance object and I was simply not assigning the attributes that were passed onto the next function to the instance object. 属性被附加到实例对象,而我只是没有将传递给下一个函数的属性分配给实例对象。

In the second (and non-functional) code, you were trying to call self.attr1 from method1 , but no such attributed existed for the Person object. 在第二个(非功能性的)代码中,您尝试从method1调用self.attr1 ,但是Person对象没有这样的属性。
method1 would have worked fine if it said print(attr1) , where attr1 is the variable that got sent in as the second argument to method1 method1 ,如果说会工作精细print(attr1) ,其中attr1是被罚在作为第二个参数变量method1

By the way, the new code would throw an error if someone tried calling method1 on an object before method2 was called. 顺便说一句,如果有人在调用method2之前尝试在对象上调用method1 ,则新代码将引发错误。 This is because the Person object doesn't have an attr1 attribute before method2 runs. 这是因为在method2运行之前,Person对象没有attr1属性。

Understanding what's going on becomes very difficult when you have similar names/string values for different things. 当您为不同的事物使用相似的名称/字符串值时,了解正在发生的事情变得非常困难。 I would suggest using different names/values for self.attr1 , attr1 and "attr1" , and it will become much more obvious why your original code wasn't working. 我建议对self.attr1attr1"attr1"使用不同的名称/值,这将变得更加显而易见,为什么您的原始代码不起作用。

The way you phrase the question suggests you're misunderstanding how attributes work. 问题表达方式暗示您误解了属性的工作原理。 Attributes pertain to the object (an instance of a class), not to the method. 属性与对象 (类的实例)有关,而与方法无关。 When you have a method like this: 当您具有这样的方法时:

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

self refers to the instance that you are calling the method on. self是您要在其上调用方法的实例。 For instance if you do bob = Person() and then bob.method2() , self will be the same object as bob . 例如,如果您先执行bob = Person()然后执行bob.method2() ,则self将与bob是同一对象。 When you do self.attr1 = 'attr1' , you set the attribute on that object. 当您执行self.attr1 = 'attr1' ,请在该对象上设置属性。 If you then call method1 , it has access to all the attributes on the object. 如果再调用method1 ,则它有权访问对象上的所有属性。 Any attributes you don't put there aren't there. 您没有放在其中的任何属性都不存在。

Simply put, if you never do self.attr1 = whatever , then trying to get the value of self.attr1 will never work. 简而言之,如果您从不执行self.attr1 = whatever ,那么尝试获取self.attr1的值将永远行不通。 In your second example, you never do self.attr1 = ... , so there is no attribute attr1 to get. 在第二个示例中,您永远不会执行self.attr1 = ... ,因此没有属性attr1可以获取。

I agree with zehnpaard that you are confusing things by using the same label attr1 as an attribute name ( self.attr1 ), a local variable name ( attr1 ), and a string value ( 'attr1' ). 我同意zehnpaard的观点,您通过使用相同的标签attr1作为属性名称( self.attr1 ),局部变量名称( attr1 )和字符串值( 'attr1' )来使事情变得混乱。 Change all of those to different things and you'll begin to see how they work differently. 将所有这些更改为不同的内容,您将开始了解它们的工作方式是否不同。

In this: 在此:

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

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

You have passed self into method1 function which stands for an instance of Person class. 您已将self传递给method1函数,该函数代表Person类的实例。 After that, you can invoke attr1 since you already have instance in method1 namespace. 在那之后,您可以调用attr1因为您已经在method1名称空间中有了实例。

That's why you don't have to pass string 'attr1' to method1 again to print. 这就是为什么您不必再次将字符串'attr1'传递给method1进行打印的原因。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM