Leia koodist wtf

elver@erlik:~$ python
Python 2.4.3 (#2, Oct 6 2006, 07:52:30)
[GCC 4.0.3 (Ubuntu 4.0.3-1ubuntu5)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> class Foo:
...   var = None
...
>>> class Bar:
...   var = [None]
...
>>> a = Foo()
>>> b = Foo()
>>> a.var = 2
>>> b.var = 4
>>> a.var
2
>>> b.var
4
>>> a = Bar()
>>> b = Bar()
>>> a.var[0] = 2
>>> b.var[0] = 4
>>> a.var
[4]
>>> b.var
[4]

See on üks nendest asjadest, mille esmakordne avastamine võtab hea mitu tundi ja rohkelt närvirakke…

9 Vastust to “Leia koodist wtf”

  1. Martin Says:

    Pointer Magic…

  2. kivipallur Says:

    Python on jah selline lahe sürrealistlik keel…
    Keep going…

  3. eigo Says:

    No mida veel, see blogi siin on ikka täitsa alla käinud!

  4. Elver Says:

    Sest sa ei õnnista meid enam oma kirjatükkidega! :(

  5. frukt Says:

    Mis toimub siis, selgitage rumalale. Esimesel juhul käitub var isendimuutujana, nagu oodatud; teisel juhul klassimuutujana. Pole pythoniga kuigi tuttav kahjuks. Vist eriti ei taha tutvuda ka kui seal sellised õudsed pitfallid sees on.

  6. Elver Says:

    See peaks vist seletama :)


    >>> class Foo:
    ... var = None
    ...
    >>> a = Foo()
    >>> b = Foo()
    >>> a.var = 4
    >>> a.var
    4
    >>> b.var
    >>> Foo.var = 15
    >>> b.var
    15
    >>> id(Foo.var)
    135535880
    >>> id(b.var)
    135535880
    >>> id(a.var)
    135536012

    “a.var = 4″ varjab klassimuutuja uue objektiga, mis kuulub edaspidi isendile, mitte klassile.

    “a.var[0] = 4″ muudab olemasolevat objekti, mis juhtub kuuluma klassile, mitte isendile.

    Kui läheb “a.var” otsimiseks (runtime’is) siis otsitakse kõigepealt isend.var’i ja seejärel klass.var’i. a.var’ile omistamisel omistatakse isend.var’ile.

  7. Ivar Zarans Says:

    Igal keelel omad veidrused ;)

    Tegelikult on Pythoni selline käitumine täiesti taotluslik ja dokumenteeritud – vaata kasvõi “Python Tutorial” nimelist dokumenti http://docs.python.org/tut/node11.html

    Seal punktis 9.1 “A Word About Terminology”, on kenasti kirjas, et:

    “Objects have individuality, and multiple names (in multiple scopes) can be bound to the same object. This is known as aliasing in other languages. This is usually not appreciated on a first glance at Python, and can be safely ignored when dealing with immutable basic types (numbers, strings, tuples). However, aliasing has an (intended!) effect on the semantics of Python code involving mutable objects such as lists, dictionaries, and most types representing entities outside the program (files, windows, etc.). This is usually used to the benefit of the program, since aliases behave like pointers in some respects.”

    Aga see, mida Sa tegelikult teha soovisid, on väikese lisakirjutamisega klassi defineerimisel täiesti tehtav.

  8. jaan Says:

    Tõesti veider ja ebaloogiline. Mehhanism on muidugi selge. Muutuja mitteleidmisel isendist saab kätte samanimelise klassi muutuja. Omistamisel aga see loogika ei tööta kuna klassi muutujale väärtuse omistamisel luuakse muutuja puudumisel automaagiliselt uus isendimuutuja. See on nüüd jälle see koht kus “skriptikeeltes” on mugav näpukaid teha ja end pooleks mõelda :)

    Tõsiseks probleemiks ma seda küll ei peaks sest, et klassi muutujaid võiks enivei küsida läbi klassi(Foo.var) ja isendimuutujad võiks olla loomisel mõistlikult väärtustatud.

  9. tom Says:

    tuleb tõesti vist järjehoidja selle lehe juures ära võtta….

Leave a Reply