问题描述
我对 Python 类的方法和属性很困惑。假设我们有一个这样的 Python 类:
# case 1
class Person:
def __init__(self,first,last):
self.first = first
self.last = last
self.fun()
def fun(self):
value = self.first + '---' + self.last
self.fun = value
return value
person_1 = Person('A','B')
person_1.fun
---> "A---B"
如我们所见,在case_1中,我们初始化了一个实例 person_1
。我们可以通过将 fun
作为属性调用来获得我们想要的结果。但是,如果我们将代码更改为以下内容,fun
将变成方法。(case_2)
# case 2
class Person:
def __init__(self,last):
self.first = first
self.last = last
self.fun()
def fun(self):
value = self.first + '---' + self.last
return value
person_1 = Person('A','B')
person_1.fun
---> <bound method Person.fun of <__main__.Person object at 0x7fd4f79168d0>>
我们仍然在类中包含 init 进程。但是现在 fun
变成了方法,而不是属性。 (案例_2)
如果我们删除 self.fun()
中的 init
但保留 self.fun = value
,它仍然是一个 方法。 (案例_3)
# case 3
class Person:
def __init__(self,last):
self.first = first
self.last = last
def fun(self):
value = self.first + '---' + self.last
self.fun = value
return value
person_1 = Person('A','B')
person_1.fun
---> <bound method Person.fun of <__main__.Person object at 0x7fd4f797f390>>
你介意给我一些关于为什么会发生这种情况的说明吗?将函数用作 Python 类中的属性的正确方法是什么?在此先感谢您!
解决方法
在第 1 种情况下,您的构造函数调用 fun() ,其中包含一行以使用属性值覆盖自身。这是令人困惑的,不是一件好事,因为它令人困惑。
在第 2 种情况下,您的 fun 方法不包含覆盖自身的行,因此不会被覆盖。
在情况 3 中,您实际上从未调用过 fun 方法,因此它永远没有机会覆盖自己。如果您使用 person_1.fun() 调用它,即使用括号,那么它将执行并覆盖自身,从那时起,person_1.fun 将是一个属性值。
请记住,在 python 中,函数/方法只有在使用括号调用时才会执行。如果不用括号表示,那么求值的结果不是函数的输出,而是表达式产生对函数本身的引用,可以放在另一个变量或数据结构中,稍后调用.
为了说明这一点:
>>> def my_func():
... print('got called')
... return 42
...
>>> x = my_func #no parentheses,x becomes an alias to my_func
>>> y = my_func() #parentheses means actually execute
got called
>>> y
42
>>> x
<function my_func at 0x765e8afdc0>
>>> x() #x is a reference to my_func and can be called itself
got called
42
>>>
,
啊哈,我想我明白了!
在情况 1 中,我们只是在初始化实例时运行函数 fun()
。并且因为它在 self.fun = value
中定义了属性 fun()
,因此 fun
可以用作属性。 (不能再作为方法使用了,因为它已经被替换为属性了。)
在情况 2 中,我们只调用并运行此函数。但是 fun
没有被定义为类内部的属性。这就是为什么它仍然是一种方法。
在情况 3 中,fun
是一个方法,但在此方法中,我们定义了一个属性 fun
。因此我们可以先初始化一个实例,然后运行函数fun
。之后,属性fun
被添加到这个实例中,然后我们可以将其称为person_1.fun
。