python - 括号对方法和“自我”变量的影响
问题描述
我一直在学习 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”的参数。但是,在后一种情况下,我不需要重新定义“自我”变量。为什么是这样?
解决方案
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'
推荐阅读
- image - 从头弹起然后倒置
- nginx - 用于编译动态模块的 nginx ./configure 在哪里?
- python - UnboundLocalError:分配前引用的局部变量“med”
- ruby - 在某些情况下,红宝石空格是否敏感?
- android - Android Canvas 改变形状和文本交集的颜色
- python - 在 Python 中将嵌套的 JSON 数组转换为简单的 JSON
- javascript - 如何在 jquery Datatable 上应用 columnDefs 并将 saveState 选项设置为 true
- ruby - 使用 docker 日志在 docker 容器中看不到 ruby 进程输出
- c# - 从用户管理器开始的 Web api 错误 500
- .htaccess - 更改为 https 时出现内部服务器错误