对象方法内部和外部的变量

时间:2018-09-10 09:07:43

标签: python class object variables methods

我刚刚开始学习Python中的类和对象,然后遇到了以下问题

在某些情况下,在我定义的方法中它似乎不适用于变量n:

例如:

def play(self):
    if n < 4:
        n += 1
        self.mood = moods[n]
    else:
        self.mood = self.mood

这引发了错误,并且在“ if n <4:”行上未定义n,但是如果我擦除此部分,则“ n + = 1”不会出现错误。但是即使在那之后,如果我在方法中使用它,似乎也不会更新变量n:

def new_mood(self):
    n = random.randint(0,2)
    self.mood = moods[n]    

我在这里缺少一些基本知识吗?

import random

moods = ['terrible', 
         'bad', 
         'neutral', 
         'good', 
         'great']

n = random.randint(0,2)

class animals:

    def __init__(self, species, name, mood):
        self.species = species
        self.name = name
        self.mood = mood

    def default_mood(self):
        self.mood = moods[2]

    def new_mood(self):
        n = random.randint(0,2)
        self.mood = moods[n]    

    def play(self):
        if n < 4:
            n += 1
            self.mood = moods[n]
        else:
            self.mood = self.mood


Max = animals('Dog', 'Max', moods[n])
Princess = animals('Cat', 'Princess', moods[n])


print(Max.name + ' mood is ' + Max.mood)
print(Princess.name + ' mood is ' + Princess.mood)

Max.new_mood()
Max.play()

Princess.play()


print(Max.name + ' mood is ' + Max.mood)
print(Princess.name + ' mood is ' + Princess.mood)

print(Max.mood)

print(Max.name + ' mood is ' + Max.mood)
print(Princess.name + ' mood is ' + Princess.mood)

1 个答案:

答案 0 :(得分:0)

TLDR:这不是由类引起的,而是由作用域在Python中起作用的方式引起的。对名称的任何赋值都会使该名称成为局部变量,从而遮盖所有相同名称的全局变量。

使用globalnonlocal显式引用全局或包含范围的名称。使用类属性从类范围引用名称。


考虑以下不带类的最小示例:

>>> n = 5
...
>>> def foo():
...    if n < 10:
...        n += 1
...
>>> foo()
UnboundLocalError: local variable 'n' referenced before assignment

请注意该错误说明 local 变量如何? n中的foo不是全局n!由于本地n直到分配时才初始化,因此无法事先在比较中使用。如果全局n不存在,您将得到并且可能还会期望相同的错误。

每当在范围内分配一个名称时,该名称就会自动成为该范围的本地名称。请注意,这会影响整个范围-包括分配之前发生的事件。如果仅执行分配,则只会更改本地名称-在范围的末尾将被丢弃。

如果要在外部范围内修改名称,则必须告诉Python。为此,存在globalnonlocal关键字:

>>> def foo():
...    global n     # n refers to the global name n for the entire scope
...    if n < 10:   # works, we compare against the global n
...        n += 1   # modifies the global n, no introduction of local n

一个相关但略有不同的用例是特定于类的变量。例如,n可能是所有animals 的功能,例如影响所有humans

此类的类属性在类的主体中定义。您可以通过类名来引用它们,类似于获取方法的方法:

class Animals:
    n = 0

    def new_mood(self):
        # we want the 'n' of Animals
        Animals.n = random.randint(0,2)
        self.mood = moods[Animals.n]  

several ways可以使用类属性,具体取决于人们想要如何处理修改和子类化。