Область Python внутри вложенной функции внутри класса?

Как установить переменную класса внутри функции внутри другой функции?

var.py

class A:
    def __init__(self):
        self.a = 1
        self.b = 2
        self.c = 3
    def seta(self):
        def afunction():
            self.a = 4
        afunction()
    def geta(self):
        return self.a

run.py

cA = A()
print cA.a
cA.seta()
print cA.a
print cA.geta()

python run.py

1
1
1

почему не равно 4 и как я могу сделать его равным 4?

Изменить:

Спасибо всем - извините, я только что видел. Я случайно был отключен _ в одном из моих имен.... так что моя сфера на самом деле все в порядке.

Ответ 1

Проблема заключается в том, что существует несколько переменных self. Аргумент, переданный в вашу внутреннюю функцию, перезаписывает область внешнего.

Вы можете преодолеть это, удалив параметр self из внутренней функции и убедившись, что вы каким-то образом вызвали эту функцию.

class A:
    def __init__(self):
        self.a = 1
        self.b = 2
        self.c = 3
    def seta(self):
        def afunction():  # no self here
            self.a = 4
        afunction()       # have to call the function
    def geta(self):
        return self.a

Ответ 2

Как уже упоминалось, afunction никогда не вызывается. Вы можете сделать что-то вроде этого:

class A:
    def __init__(self):
        self.a = 1

    def seta(self):
        def afunction(self):
            self.a = 4
        afunction(self)

    def geta(self):
        return self.a

a = A()
print a.a
a.seta()
print a.a

Здесь мы на самом деле вызываем afunction и явно передаем его self, но это довольно глупый способ установить атрибут a - особенно, когда мы можем сделать это явно, без необходимости в getters или seters: a.a = 4

Или вы могли бы return выполнить функцию:

def seta(self):
    def afunction(): #Don't need to pass `self`.  It gets picked up from the closure
        self.a = 4
    return afunction

а затем в коде:

a = A()
a.seta()()  #the first call returns the `afunction`, the second actually calls it.

Ответ 3

Внутри seta вы определяете функцию

    def afunction(self):
        self.a = 4

..., который установил бы self.a в 4, если он когда-либо будет вызван. Но он не называется нигде, поэтому a не изменяется.

Ответ 4

Как уже говорили некоторые другие, в какой-то момент вам нужно фактически вызвать функцию. Комментарии не позволят мне вводить это разумно, поэтому вот ответ:

def seta(self):
    def functiona(self):  #defined
        self.a = 4
    functiona()           #called

Ответ 5

Как вы можете сделать это равным 4:

class A:
    def __init__(self):
        self.a = 1
        self.b = 2
        self.c = 3
    def seta(self):
        ##def afunction(self): (remove this)
        self.a = 4 
    def geta(self):
        return self.a

Трудная часть: почему это не соответствует 4...

В настоящее время a устанавливается в 4 только через "afunction". Поскольку функция никогда не называется, она никогда не выполняется. У сетки есть "функция", вложенная внутри, но не вызываемая... подобно переменным-членам в классах.