为什么在Pythonclass__init__里面调用函数既可以是Attribute又可以是Method?
Why calling a function inside a Python class __init__ can be both Attribute and Method?
我对 Python class 的 方法 和 属性 感到很困惑。假设我们有一个 Python class 这样的:
# 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, first, 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>>
我们仍然在 class 中包含 init 进程。但是现在 fun
变成了 方法 而不是 属性 。 (case_2)
如果我们删除init
中的self.fun()
但保留self.fun = value
,它仍然是方法。 (case_3)
# case 3
class Person:
def __init__(self, first, 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 Class 中的属性的正确方法是什么?提前致谢!
啊哈,我想我明白了!
在情况 1 中,我们在初始化实例时简单地 运行 函数 fun()
。并且因为它在fun()
中定义了属性self.fun = value
,因此fun
可以用作属性。 (它不能再用作方法,因为它已被替换为属性。)
情况2,我们只调用和运行这个函数。但是 fun
没有被定义为 class 里面的属性。这就是为什么它仍然作为一种方法。
案例3中,fun
是一个方法,但是在这个方法中,我们定义了一个属性fun
。因此我们可以先初始化一个实例,然后 运行 函数 fun
。之后,属性fun
被添加到这个实例,然后我们可以称它为person_1.fun
.
在情况 1 中,您的构造函数调用 fun(),其中有一行代码用属性值覆盖自身。这很混乱,也不是一件好事,因为它很混乱。
在情况 2 中,您的 fun 方法不包含覆盖自身的行,因此它不会被覆盖。
在情况 3 中,您实际上从未调用过有趣的方法,因此它永远没有机会覆盖自身。如果你用 person_1.fun() 调用它,即带括号,那么它会执行并覆盖自己,从那时起,person_1.fun 将是一个属性值。
请记住,在 python 中,function/method 仅在使用括号调用时执行。如果不使用括号表示,那么计算结果不是函数的输出,而是表达式产生对函数本身的引用,可以将其放入另一个变量或数据结构中,稍后调用.
为了说明这一点:
>>> 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
>>>
我对 Python class 的 方法 和 属性 感到很困惑。假设我们有一个 Python class 这样的:
# 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, first, 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>>
我们仍然在 class 中包含 init 进程。但是现在 fun
变成了 方法 而不是 属性 。 (case_2)
如果我们删除init
中的self.fun()
但保留self.fun = value
,它仍然是方法。 (case_3)
# case 3
class Person:
def __init__(self, first, 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 Class 中的属性的正确方法是什么?提前致谢!
啊哈,我想我明白了!
在情况 1 中,我们在初始化实例时简单地 运行 函数 fun()
。并且因为它在fun()
中定义了属性self.fun = value
,因此fun
可以用作属性。 (它不能再用作方法,因为它已被替换为属性。)
情况2,我们只调用和运行这个函数。但是 fun
没有被定义为 class 里面的属性。这就是为什么它仍然作为一种方法。
案例3中,fun
是一个方法,但是在这个方法中,我们定义了一个属性fun
。因此我们可以先初始化一个实例,然后 运行 函数 fun
。之后,属性fun
被添加到这个实例,然后我们可以称它为person_1.fun
.
在情况 1 中,您的构造函数调用 fun(),其中有一行代码用属性值覆盖自身。这很混乱,也不是一件好事,因为它很混乱。
在情况 2 中,您的 fun 方法不包含覆盖自身的行,因此它不会被覆盖。
在情况 3 中,您实际上从未调用过有趣的方法,因此它永远没有机会覆盖自身。如果你用 person_1.fun() 调用它,即带括号,那么它会执行并覆盖自己,从那时起,person_1.fun 将是一个属性值。
请记住,在 python 中,function/method 仅在使用括号调用时执行。如果不使用括号表示,那么计算结果不是函数的输出,而是表达式产生对函数本身的引用,可以将其放入另一个变量或数据结构中,稍后调用.
为了说明这一点:
>>> 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
>>>