首页 > 解决方案 > 括号对方法和“自我”变量的影响

问题描述

我一直在学习 Python 中 OOP 实现的一些基础知识。我在做实验,注意到当我在定义对象时没有添加括号时,类中的方法需要我定义 self.

因为我是 OOP 的新手,所以除了在 stackoverflow 上发布问题外,我真的不知道在哪里可以找到像这样的利基问题的答案。

为了更具体一点,这是我正在运行的代码:

class Person():
    def introduction(self):
        print(f"Hi, my name's {self.name}. What's yours?")

Aaron = Person
Aaron.name = "Aaron"
Aaron.introduction()

Betty = Person()
Betty.name = "Betty"
Betty.introduction()

在前一种情况下,方法介绍要求我再次输入 Aaron 以使其工作,否则它会告诉我我缺少变量“self”的参数。但是,在后一种情况下,我不需要重新定义“自我”变量。为什么是这样?

标签: pythonclassoop

解决方案


In [1]: class Person(): 
   ...:     def introduction(self): 
   ...:         print(f"Hi, my name's {self.name}. What's yours?") 
   ...:                                                                                                      

Person是类:

In [2]: Person                                                                                               
Out[2]: __main__.Person

introduction是一个类方法。它应该通过实例调用,而不是类本身。如果通过类调用,它就像调用一个需要正确参数的函数:

In [3]: Person.introduction()                                                                                
....
TypeError: introduction() missing 1 required positional argument: 'self'

In [4]: Person.introduction('foobar')                                                                        
...
<ipython-input-1-3d4d3d4fd6be> in introduction(self)
      1 class Person():
      2     def introduction(self):
----> 3         print(f"Hi, my name's {self.name}. What's yours?")

AttributeError: 'str' object has no attribute 'name'

你的Aaron=Person任务只是分散注意力。它不会创造任何新东西。这只是引用类的另一种方式。

定义一个类实例:

In [5]: betty = Person()                                                                                     
In [6]: betty                                                                                                
Out[6]: <__main__.Person at 0x7f44603ccb00>

现在如果我们使用introduction方法,self就是实例本身。但与之前的通话一样,self需要name

In [7]: betty.introduction()                                                                                 
....
<ipython-input-1-3d4d3d4fd6be> in introduction(self)
      1 class Person():
      2     def introduction(self):
----> 3         print(f"Hi, my name's {self.name}. What's yours?")

AttributeError: 'Person' object has no attribute 'name'

正如您所做的那样,我们可以为实例分配一个属性(但通常我们在 中进行这种分配__init__):

In [8]: betty.name = 'foobar'                                                                                
In [9]: betty.introduction()                                                                                 
Hi, my name's foobar. What's yours?

一个更完整的类定义应该有一个__init__和一个显示方法:

In [10]: class Person(): 
    ...:     def __init__(self, name): 
    ...:         self.name = name 

    ...:     def introduction(self): 
    ...:         print(f"Hi, my name's {self.name}. What's yours?") 

    ...:     def __repr__(self): 
    ...:         return f'Person named {self.name}' 
    ...:                                                                                                     
In [11]: betty=Person('betty')                                                                               
In [12]: betty                                                                                               
Out[12]: Person named betty      # the repr display
In [13]: betty.introduction()                                                                                
Hi, my name's betty. What's yours?

如果您确实想通过将方法Person.func定义为classmethod. 但这是一个可以等待的高级主题。

如果我添加到类定义中:

...:     @classmethod 
...:     def classintro(cls): 
...:         return f'Person class name is {cls.name}' 
...:     name = 'Person' 

该类现在有一个name属性和显示它的方法:

In [23]: Person.name                                                                                         
Out[23]: 'Person'
In [24]: Person.classintro()                                                                                 
Out[24]: 'Person class name is Person'

并且实例可以访问这两种方法:

In [25]: betty = Person('betty')                                                                             
In [26]: betty.introduction()                                                                                
Hi, my name's betty. What's yours?
In [27]: betty.classintro()                                                                                  
Out[27]: 'Person class name is Person'

推荐阅读