Python 为什么同一条语句打印两个不同的值?

Python 为什么同一条语句打印两个不同的值?,python,Python,在我试图理解python的自我概念时,我遇到了这个我认为有用的例子。但有一部分让我困惑。为什么打印a.i输出两个不同的值?在第一种情况下,输出是5,这对我来说很有意义。但几行之后,相同的print a.i语句输出123 def say_hi(): return 'hi!' i = 789 class MyClass(object): i = 5 def prepare(self): i = 10 self.i = 123

在我试图理解python的自我概念时,我遇到了这个我认为有用的例子。但有一部分让我困惑。为什么
打印a.i
输出两个不同的值?在第一种情况下,输出是
5
,这对我来说很有意义。但几行之后,相同的
print a.i
语句输出
123

def say_hi():
    return 'hi!'

i = 789

class MyClass(object):

    i = 5

    def prepare(self):
        i = 10
        self.i = 123
        print i

    def say_hi(self):
        return 'Hi there!'

    def say_something(self):
        print say_hi()

    def say_something_else(self):
        print self.say_hi()
输出

>>> print say_hi()
hi!
>>> print i
789
>>> a = MyClass()
>>> a.say_something()
hi!
>>> a.say_something_else()
Hi there!
>>> print a.i
5
>>> a.prepare()
10
>>> print i
789
>>> print a.i
123

prepare
方法中的以下语句之前:

self.i = 123
self.i
引用类属性
MyClass.i
(因为未设置实例属性)


执行
self.i=..
语句后,
self.i
引用一个新值
123
。(这不会影响类属性
MyClass.i
,创建一个新的实例属性)

您正在
prepare()
函数中将类变量i更改为123:

    self.i = 123

之后,您通过执行打印a.i来调用类变量,结果将打印123。

您使用的是具有相同名称的全局、局部和实例属性:

def say_hi():        # This is the global function 'say_hi'
    return 'hi!'    

i = 789              # This is the global 'i'

class MyClass(object):

    i = 5  # This is a class attribute 'i'

    def prepare(self):
        i = 10           # Here, you are creating a new 'i' (local to this function)
        self.i = 123     # Here, you are changing the instance attribute 'i'
        print i          # Here, you are printing the new'ed 'i' (now with value 10)

    def say_hi(self):         # This is the object method 'say_hi' function
        return 'Hi there!'

    def say_something(self):
        print say_hi()         # Here, you are calling the global 'say_hi' function

    def say_something_else(self):
        print self.say_hi()    # Here, you are calling the object method 'say_hi' function
因此输出是正确的:

>>> print say_hi()          # global
hi!
>>> print i                 # global
789
>>> a = MyClass()
>>> a.say_something()       # say_something calls the global version
hi!
>>> a.say_something_else()  # say_something_else calls the object version
Hi there!
>>> print a.i               # class attribute 'i'
5
>>> a.prepare()             # prints the local 'i' and change the class attribute 'i'
10
>>> print i                 # global 'i' is not changed at all
789
>>> print a.i               # class attribute 'i' changed to 123 by a.prepare()
123

但我认为赛尔夫是在指出这个例子;不是这个班吗?换句话说,self.i正在更改实例a中的值,但不更改类变量。self.i(或a.i)不引用类变量(或属性)-它是一个实例属性。self.i引用一个实例属性-MyClass。我引用一个类属性-两件截然不同的事情。@TonySuffolk66,
self.i
在没有名为
i
的实例属性时引用类属性。好的-我承认您是正确的。。。。我希望没有人编写过使用它的生产代码。…@TonySuffolk66,它很常用,即使在标准库中也是如此。例如,@TonySuffolk66,仅供参考,在中搜索
类属性
。(第二次出现)我会使用术语实例属性(而不是对象属性-在python中proerty是一个非常特殊的东西),但这是范围和实例属性方面的正确答案。@TonySuffolk66谢谢,我修复了这个问题。更令人困惑的是,第一个
a.I
不是实例属性,而是类属性
prepare
通过创建实例属性来屏蔽它。@YannVernier谢谢,我修复了
类属性“I”被a.prepare()更改为123的问题:否。
a.prepare()
将类属性更改为
10
,并创建实例属性
self.I=123
您调用
a.prepare()
,其中您有
self.i=123