🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Thread View: pl.comp.lang.python
9 messages
9 total messages Started by Daniel Mróz Thu, 10 Jun 2010 20:58
Magiczne dzieci
#27504
Author: Daniel Mróz
Date: Thu, 10 Jun 2010 20:58
81 lines
2544 bytes
Cześć

Ja już zgłupiałem. Czy ktoś mi może wyjaśnić coś takiego:

---------------------------------------------------------
class A(object):
    def __init__(self, name=None):
        self.name = name
        self.children = {}
        
        
    def add_child(self, child):
        self.children[child.name] = child
        
        
        
a = A()
a1 = A('1')
a1.add_child(A('1.1'))
a1.add_child(A('1.2'))
a.add_child(a1)

print a.children.keys()
---------------------------------------------------------

Po odpaleniu tego kodu mam wynik:


['1']


czyli prawidłowo.
Teraz robimy drobną zmianę:

---------------------------------------------------------
class A(object):
    def __init__(self, name=None, children={}):
        self.name = name
        self.children = children
        
        
    def add_child(self, child):
        self.children[child.name] = child
        
        
        
a = A()
a1 = A('1')
a1.add_child(A('1.1'))
a1.add_child(A('1.2'))
a.add_child(a1)

print a.children.keys()
---------------------------------------------------------

Po odpaleniu mamy:


['1', '1.1', '1.2']


O co tu chodzi? Nazwa argumentu nie ma znaczenia. Jeśli tylko będzie
jakikolwiek z wartością domyślną {}, to atrybut children obiektu nadrzędnego
przejmuje wartość atrybutu children obiektu podrzędnego przy przypisaniu:


self.children[child.name] = child


Jakim cudem? Czy może ja gdzieś robię błąd, którego nie widzę (późno już)?



Pozdrawiam
Beorn

-- 
Daniel 'Beorn' Mróz <beorn@alpha.pl>    http://127.0.0.1/beorn
[GIT d s:- a-@ C++++ UL++++$ P+ L++++ E--- W+ N+++ o? K- w---]
[O- M- V!  PS+ PE++ Y+ PGP++ t- 5  X R !tv b+ DI D++ G++ e h*]
[                          r++  y+                           ]
Re: Magiczne dzieci
#27505
Author: Wojciech Muła
Date: Thu, 10 Jun 2010 21:09
23 lines
1401 bytes
Daniel Mróz <beorn@alpha.pl> wrote:

> class A(object):
>     def __init__(self, name=None, children={}):
>         self.name = name
          print id(children)
>         self.children = children
          print id(self.children)
>         
>         
>     def add_child(self, child):
>         self.children[child.name] = child

Jak uruchomisz, zobaczysz, że wszystkie instancje klasy dostają
ten sam obiekt słownika i na nim operują. Spróbuj dać na początku

import copy

a w konstruktorze

	self.children = copy.copy(children)

w.
Re: Magiczne dzieci
#27506
Author: Daniel Mróz
Date: Thu, 10 Jun 2010 21:16
14 lines
1414 bytes
On 10.06.2010, Wojciech Muła <wojciech_mula@poczta.null.onet.pl.invalid> wrote:
> Jak uruchomisz, zobaczysz, że wszystkie instancje klasy dostają
> ten sam obiekt słownika i na nim operują. Spróbuj dać na początku
No tak. Masz rację. Dzięki za pomoc.


Pozdrawiam
Beorn

-- 
Daniel 'Beorn' Mróz <beorn@alpha.pl>    http://127.0.0.1/beorn
[GIT d s:- a-@ C++++ UL++++$ P+ L++++ E--- W+ N+++ o? K- w---]
[O- M- V!  PS+ PE++ Y+ PGP++ t- 5  X R !tv b+ DI D++ G++ e h*]
[                          r++  y+                           ]
Re: Magiczne dzieci
#27512
Author: Wojciech Malinowski
Date: Thu, 10 Jun 2010 21:16
16 lines
1494 bytes
On 06/10/10 22:58, Daniel Mróz wrote:
> O co tu chodzi? Nazwa argumentu nie ma znaczenia. Jeśli tylko będzie
> jakikolwiek z wartością domyślną {}, to atrybut children obiektu nadrzędnego
> przejmuje wartość atrybutu children obiektu podrzędnego przy przypisaniu:
> 
> self.children[child.name] = child
> 
> Jakim cudem? Czy może ja gdzieś robię błąd, którego nie widzę (późno już)?

Wszystko działa jak należy. Wystarczy czytać dokumentację ;>

http://docs.python.org/tutorial/controlflow.html#default-argument-values
(jest tam pogrubione important warning)

Pozdrawiam,
Wojciech Malinowski
Re: Magiczne dzieci
#27507
Author: Artur M. Piwko
Date: Fri, 11 Jun 2010 05:55
29 lines
1771 bytes
In the darkest hour on Thu, 10 Jun 2010 23:09:26 +0200,
Wojciech Muła <wojciech_mula@poczta.null.onet.pl.invalid> screamed:
>> class A(object):
>>     def __init__(self, name=None, children={}):
>>         self.name = name
>           print id(children)
>>         self.children = children
>           print id(self.children)
>
> Jak uruchomisz, zobaczysz, że wszystkie instancje klasy dostają
> ten sam obiekt słownika i na nim operują. Spróbuj dać na początku
>
> import copy
>
> a w konstruktorze
>
> 	self.children = copy.copy(children)
>

Albo:

def __init__(self, name=None, children=None):
    self.children = {} if children is None else children

-- 
[ Artur M. Piwko : Pipen : AMP29-RIPE : RLU:100918 : From == Trap! : SIG:234B ]
[ 07:54:37 user up 12465 days, 19:49,  1 user, load average: 0.36, 0.95, 0.00 ]

      If you've got them by the balls their hearts and minds will follow.
Re: Magiczne dzieci
#27508
Author: Piotr Husiatynski
Date: Fri, 11 Jun 2010 06:50
31 lines
1803 bytes
Dnia 11.06.2010 Artur M. Piwko <milusi.pysiaczek@buziaczek.pl> napisał/a:
> In the darkest hour on Thu, 10 Jun 2010 23:09:26 +0200,
> Wojciech Muła <wojciech_mula@poczta.null.onet.pl.invalid> screamed:
>>> class A(object):
>>>     def __init__(self, name=None, children={}):
>>>         self.name = name
>>           print id(children)
>>>         self.children = children
>>           print id(self.children)
>>
>> Jak uruchomisz, zobaczysz, że wszystkie instancje klasy dostają
>> ten sam obiekt słownika i na nim operują. Spróbuj dać na początku
>>
>> import copy
>>
>> a w konstruktorze
>>
>> 	self.children = copy.copy(children)
>>
>
> Albo:
>
> def __init__(self, name=None, children=None):
>     self.children = {} if children is None else children
>

def __init__(self, name=None, children=None):
    self.children = children or {}

-- 
Piotr Husiatyński
Re: Magiczne dzieci
#27509
Author: Artur M. Piwko
Date: Fri, 11 Jun 2010 20:57
30 lines
1861 bytes
In the darkest hour on Fri, 11 Jun 2010 06:50:13 +0000 (UTC),
Piotr Husiatynski <husio@gmail.com> screamed:
>>> Jak uruchomisz, zobaczysz, że wszystkie instancje klasy dostają
>>> ten sam obiekt słownika i na nim operują. Spróbuj dać na początku
>>>
>>> import copy
>>>
>>> a w konstruktorze
>>>
>>> 	self.children = copy.copy(children)
>>>
>>
>> Albo:
>>
>> def __init__(self, name=None, children=None):
>>     self.children = {} if children is None else children
>>
>
> def __init__(self, name=None, children=None):
>     self.children = children or {}
>

W tym przypadku pewnie nie zajdzie taka okoliczność, ale należy
pamiętać, że to nie to samo.

-- 
[ Artur M. Piwko : Pipen : AMP29-RIPE : RLU:100918 : From == Trap! : SIG:228B ]
[ 22:57:10 user up 12465 days, 10:52,  1 user, load average: 0.36, 0.95, 0.00 ]

             Got a dictionary?  I want to know the meaning of life.
Re: Magiczne dzieci
#27510
Author: Jan Kaliszewski
Date: Tue, 15 Jun 2010 21:25
28 lines
1681 bytes
Artur M. Piwko dixit (Fri, 11 Jun 2010 22:57:37 +0200):

> In the darkest hour on Fri, 11 Jun 2010 06:50:13 +0000 (UTC), Piotr
> Husiatynski <husio@gmail.com> screamed:

>>> def __init__(self, name=None, children=None):
>>>     self.children = {} if children is None else children
>>>
>>>
>> def __init__(self, name=None, children=None):
>>     self.children = children or {}
>>
>>
> W tym przypadku pewnie nie zajdzie taka okoliczność, ale należy
> pamiętać, że to nie to samo.

Nie tylko nie to samo, ale wręcz (to ostatnie rozwiązanie) proszenie się 
o kłopoty (bo niespójne: inna semantyka dla słownika pustego, inna dla 
niepustego).

pozdr.
*j




-- 
Jan Kaliszewski (zuo)
Re: Magiczne dzieci
#27511
Author: Jan Kaliszewski
Date: Fri, 18 Jun 2010 16:09
31 lines
1860 bytes
Napisałem:

> Nie tylko nie to samo, ale wręcz (to ostatnie rozwiązanie) proszenie się
> o kłopoty (bo niespójne: inna semantyka dla słownika pustego, inna dla
> niepustego).

Podam przykład:


def funkcja(s=None):
     slownik = s or {}
     slownik.clear()
     slownik.update(a=1, b=2, c=3)
     print slownik
     return slownik

s = dict(z=89)  # niepusty
s2 = funkcja(s) # -> wypisze: {'a': 1, 'c': 3, 'b': 2}
print s is s2   # -> wypisze: True
s.update(x='ala ma kota')
print s         # -> wypisze: {'a': 1, 'x': 'ala ma kota', 'c': 3, 'b': 2}

s = dict()      # pusty
s2 = funkcja(s) # -> wypisze: {'a': 1, 'c': 3, 'b': 2}
print s is s2   # -> wypisze: False
s.update(x='ala ma kota')
print s         # -> wypisze: {'x': 'ala ma kota'}


Pozdr.
*j
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads