Mam pytanie dotyczące zmiennych Pythona i klasy zainicjowanych.

Niedawno zauważyłem w Pythonie (2.7.x), że jeśli ustawisz zmienną klasową, która nie została zdefiniowana ani inicjowana, nadal jesteś w stanie zadzwonić i uzyskać dostęp do danych w ramach tej zmiennej.

Na przykład:

class Test:
    def __init__(self):
        self.a = "Hello"


t = Test()
print t.a
t.b = "World"
print t.b

Wynik:

Hello
World

Spodziewałbym się, że "Drukuj T.B" do błędu, ponieważ b nie został zdefiniowany w klasie testowej (), ale działa bez żadnego problemu. Dlaczego to się dzieje? Czy ktoś może wyjaśnić?

http://ideone.com/f2lxlh.

Dziękuję za Twój czas.

1
FunkyFresh 2 grudzień 2013, 23:00

3 odpowiedzi

Najlepsza odpowiedź

Z Dokumentów na Obiekty instancji (t jest obiekt instancji, ponieważ jest instancją klasy niestandardowej Test):

Nie należy zadeklarować atrybuty danych; Podobnie jak zmienne lokalne, wiosną do istnienia, gdy są po raz pierwszy przypisane.

Można jednak uzyskać oczekiwane zachowania za pomocą __slots__ a Klasa w nowej stylu. Niniejsze przesłonięte domyślne przechowywanie do atrybutów, aby obiekt był bardziej wydajny pamięci, a także wynika w atrybuteErrorze, jeśli spróbujesz przypisać do atrybutu, który nie został zdefiniowany w __slots__, na przykład:

>>> class Test(object):
...     __slots__ = ['a']
...
>>> t = Test()
>>> t.a = "Hello"
>>> t.b = "World"
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'Test' object has no attribute 'b'
6
Andrew Clark 2 grudzień 2013, 19:12

To jest oczekiwane zachowanie. Możesz dodać atrybuty w Pythonie w dowolnym momencie bez błędów. Nawet bez ustawiania atrybutów w __init__ Możesz dodać nowe w locie:

>>> class Test:
...     pass
...
>>> t = Test()
>>> t.foo = '3'
>>> t.foo
'3'
2
Simeon Visser 2 grudzień 2013, 19:03

Jeśli chcesz. "Nofollow"> Dokumenty )

class Test:
    def __init__(self):
        self.__dict__[ 'a' ] = "Hello"

    def __setattr__( self, name, value ):
        if name not in self.__dict__:
            raise Exception( 'No attribute: ' + name )
        else:
            self.__dict__[ name ] = value

t = Test()
t.a  = 'hello world'
print ( t.a )
t.b = "World"   # <<< this will throw exception
1
behzad.nouri 2 grudzień 2013, 19:32