2013-01-16 30 views
7

Jak ustawić zmienną klasy z funkcji wewnątrz innej funkcji?Zakres w języku Python wewnątrz funkcji zagnieżdżonej wewnątrz klasy?

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() 

pyton run.py

1 
1 
1 

Dlaczego nie równa 4 i jak mogę to zrobić równa 4?

Dzięki

Niestety, mój oryginalny kod jako afunction nazwie - zapomniałem.

Edytuj:

Dziękuję wszystkim - przepraszam, właśnie widziałem. Przypadkowo zostałem przez _ w jednym z moich nazwisk .... więc mój zakres jest w zasadzie w porządku.

+3

Nawet nie wywołałeś w swoim kodzie "afunction()". –

+6

Nie powinieneś zmieniać swojego kodu w odpowiedzi. Nie jest pomocne, jeśli musimy przejrzeć poprawki, aby zobaczyć, na jakie pytanie udzielono odpowiedzi. – TheHerk

Odpowiedz

6

Problem polega na tym, że istnieje wiele zmiennych self. Argument przekazany do wewnętrznej funkcji nadpisuje zakres zewnętrzny.

Możesz tego uniknąć przez usunięcie parametru self z funkcji wewnętrznej i upewnienie się, że wywołasz tę funkcję w jakiś sposób.

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 
1

Wewnątrz seta można zdefiniować funkcję

def afunction(self): 
     self.a = 4 

... że byself.a ustawiony na 4, czy to kiedykolwiek nazwać. Ale nie jest nigdzie wywoływany, więc a pozostaje niezmieniony.

2

Jak już wspomniano, afunction nigdy nie jest wywoływana. Można zrobić coś takiego:

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 

Tutaj faktycznie nazywamy afunction i wyraźnie przekazać go self, ale jest to raczej głupi sposób, aby ustawić atrybut a - zwłaszcza, gdy możemy to zrobić jawnie, bez potrzeby getters lub ustawiaczy: a.a = 4

Albo można return funkcję:

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

a następnie w kodzie:

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

Ponieważ kilka mówili inni, trzeba rzeczywiście wezwanie funkcjonalnie urządzonych w pewnym momencie.Komentarze nie pozwoli mi wpisać ten intelligably tak oto odpowiedź:

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

To nie powinno działać. Przynajmniej w Pythonie 3 otrzymasz komunikat o błędzie 'brak 1 wymaganego argumentu pozycyjnego: 'self''. Będziesz musiał wywołać 'functiona (self)', ale nadal to rozwiązanie jest zbędne w definiowaniu funkcji zagnieżdżonej. – Yeo

+0

Nie zauważyłeś, że to było definiowanie czegoś w zakresie klasy w pierwotnym pytaniu. –

0

Jak można je przyrównać do 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 

Tricky część: Dlaczego nie jest równoznaczny z 4 ...

Obecnie a jest ustawione na 4 tylko za pośrednictwem "afunction". Ponieważ afunction nigdy nie jest wywoływane, nigdy nie jest wykonywane. Seta ma "afunction" zagnieżdżone wewnątrz, ale nie wywoływane ... podobne do zmiennych członkowskich w obrębie klas.