Thread View: pl.comp.lang.python
15 messages
15 total messages
Started by hubert depesz lubaczewski
Tue, 15 Nov 2011 02:48
Prośba o wytknięcie błędów
Author: hubert depesz lubaczewski
Date: Tue, 15 Nov 2011 02:48
Date: Tue, 15 Nov 2011 02:48
71 lines
2740 bytes
2740 bytes
elo
jako pierwsze coś napisałem program wyszukujący duplikaty maili.
funkcjonalność jest relatywnie mało istotna - chodzi mi o to czy
moglisbyście mi powiedzieć co zrobiłem nie po pythonowemu, lub co można
zrobić lepiej/bardziej pythonowo.
dzięki,
depesz
---------
#!/usr/bin/env python
from os.path import walk, join, getsize, isfile, basename
import email
import sys
from hashlib import sha256
from pipes import quote
import pprint
def calculate_hash( filename ):
f = open( filename, 'r' )
mail = email.message_from_file( f )
keep_headers = ( 'subject', 'from', 'to', 'cc', 'in-reply-to', 'references', 'date', 'message-id', 'content-type', 'mime-version' )
for h in mail.keys():
if h.lower() not in keep_headers:
del mail[ h ]
return sha256( mail.as_string() ).hexdigest()
def visit_fn( hash_dict, path, files ):
for i in [ 'new', 'tmp' ]:
if files.count ( i ) > 0:
files.remove( i )
if basename( path ) != 'cur':
return
for file in files:
full_path=join( path, file )
if not isfile( full_path ):
continue
if getsize( full_path ) > 10 * 1024 * 1024:
continue
checksum = calculate_hash( full_path )
if not hash_dict.has_key( checksum ):
hash_dict[ checksum ] = list()
hash_dict[ checksum ].append( full_path )
hash_dict = dict()
walk( sys.argv[1], visit_fn, hash_dict )
for i in hash_dict.keys():
if len( hash_dict[i] ) == 1:
del hash_dict[i]
for sha in hash_dict.keys():
print "# %s" % ( sha )
print "# keep: %s" % ( hash_dict[ sha ][0] )
print "rm", " ".join( [ quote(i) for i in hash_dict[ sha ][1:] ] )
print
---------
--
The best thing about modern society is how easy it is to avoid contact with it.
http://depesz.com/
Re: Prośba o wytknięcie błędów
Author: Artur M. Piwko
Date: Tue, 15 Nov 2011 08:19
Date: Tue, 15 Nov 2011 08:19
61 lines
2725 bytes
2725 bytes
In the darkest hour on Tue, 15 Nov 2011 03:48:34 +0100,
hubert depesz lubaczewski <depesz@depesz.com> screamed:
> def calculate_hash( filename ):
> f = open( filename, 'r' )
> mail = email.message_from_file( f )
> keep_headers = ( 'subject', 'from', 'to', 'cc', 'in-reply-to', 'references', 'date', 'message-id', 'content-type', 'mime-version' )
> for h in mail.keys():
> if h.lower() not in keep_headers:
> del mail[ h ]
> return sha256( mail.as_string() ).hexdigest()
>
W obecnych Pythonach możesz stosować konstrukcję (automagicznie zamknie uchwyt):
def calculate_hash(filename):
with open(filename) as f:
mail = .....
f = open(filename, 'r') to to samo co f = open(filename)
> def visit_fn( hash_dict, path, files ):
> for i in [ 'new', 'tmp' ]:
> if files.count ( i ) > 0:
> files.remove( i )
>
Tu lepiej użyć tupli ('new', 'tmp').
> checksum = calculate_hash( full_path )
> if not hash_dict.has_key( checksum ):
> hash_dict[ checksum ] = list()
> hash_dict[ checksum ].append( full_path )
>
> hash_dict = dict()
>
Alternatywnie (z tym, że trzeba uważać):
hash_dict[checksum] = []
hash_dict = {}
Oprócz konstrukcji: if not d.has_key(k):
można też używać: if k not in d:
Dla mnie ta druga jest czytelniejsza.
> walk( sys.argv[1], visit_fn, hash_dict )
>
> for i in hash_dict.keys():
> if len( hash_dict[i] ) == 1:
> del hash_dict[i]
>
> for sha in hash_dict.keys():
> print "# %s" % ( sha )
Alternatywnie, po prostu: print '#', sha
--
[ Artur M. Piwko : Pipen : AMP29-RIPE : RLU:100918 : From == Trap! : SIG:239B ]
[ 09:10:35 user up 12987 days, 21:05, 1 user, load average: 0.09, 0.04, 0.35 ]
Peace: In international affairs, a period of cheating between two countries.
Re: Prośba o wytknięcie błędów
Author: Adam Przybyla
Date: Tue, 15 Nov 2011 09:09
Date: Tue, 15 Nov 2011 09:09
76 lines
3097 bytes
3097 bytes
hubert depesz lubaczewski <depesz@depesz.com> wrote: > elo > jako pierwsze coś napisałem program wyszukujący duplikaty maili. > > funkcjonalność jest relatywnie mało istotna - chodzi mi o to czy > moglisbyście mi powiedzieć co zrobiłem nie po pythonowemu, lub co można > zrobić lepiej/bardziej pythonowo. > > dzięki, > > depesz > > > --------- > #!/usr/bin/env python > from os.path import walk, join, getsize, isfile, basename > import email > import sys > from hashlib import sha256 > from pipes import quote > import pprint > > def calculate_hash( filename ): > f = open( filename, 'r' ) > mail = email.message_from_file( f ) > keep_headers = ( 'subject', 'from', 'to', 'cc', 'in-reply-to', 'references', 'date', 'message-id', 'content-type', 'mime-version' ) > for h in mail.keys(): > if h.lower() not in keep_headers: > del mail[ h ] > return sha256( mail.as_string() ).hexdigest() ... mozna to napisac krocej: def calculate_hash( filename ): mail=email.message_from_file(open(filename)) [mail.__delitem__(h) for h in mail.keys() if h.lower not in keep_headers] return sha256( mail.as_string() ).hexdigest() > > def visit_fn( hash_dict, path, files ): > for i in [ 'new', 'tmp' ]: > if files.count ( i ) > 0: > files.remove( i ) > > if basename( path ) != 'cur': > return > > for file in files: > full_path=join( path, file ) > > if not isfile( full_path ): > continue > > if getsize( full_path ) > 10 * 1024 * 1024: > continue > > checksum = calculate_hash( full_path ) > if not hash_dict.has_key( checksum ): > hash_dict[ checksum ] = list() > hash_dict[ checksum ].append( full_path ) > > > hash_dict = dict() > > walk( sys.argv[1], visit_fn, hash_dict ) > > for i in hash_dict.keys(): > if len( hash_dict[i] ) == 1: > del hash_dict[i] > > for sha in hash_dict.keys(): > print "# %s" % ( sha ) > print "# keep: %s" % ( hash_dict[ sha ][0] ) > print "rm", " ".join( [ quote(i) for i in hash_dict[ sha ][1:] ] ) > print > --------- > Z powazaniem Adam Przybyla
Re: Prośba o wytknięcie błędów
Author: Stachu 'Dozzie' K.
Date: Tue, 15 Nov 2011 09:34
Date: Tue, 15 Nov 2011 09:34
15 lines
1637 bytes
1637 bytes
On 2011-11-15, Artur M. Piwko <milusi.pysiaczek@buziaczek.pl> wrote:
>> def visit_fn( hash_dict, path, files ):
>> for i in [ 'new', 'tmp' ]:
>> if files.count ( i ) > 0:
>> files.remove( i )
>>
>
> Tu lepiej użyć tupli ('new', 'tmp').
Tupla ma strukturę, nie kolejność. Tu chodziło o listę elementów.
Semantycznie poprawniejszą jest lista w tym przypadku.
--
Secunia non olet.
Stanislaw Klekot
Re: Prośba o wytknięcie błędów
Author: hubert depesz lubaczewski
Date: Tue, 15 Nov 2011 14:12
Date: Tue, 15 Nov 2011 14:12
73 lines
3151 bytes
3151 bytes
On 2011-11-15, Artur M. Piwko <milusi.pysiaczek@buziaczek.pl> wrote:
> In the darkest hour on Tue, 15 Nov 2011 03:48:34 +0100,
> hubert depesz lubaczewski <depesz@depesz.com> screamed:
>> def calculate_hash( filename ):
>> f = open( filename, 'r' )
>> mail = email.message_from_file( f )
>> keep_headers = ( 'subject', 'from', 'to', 'cc', 'in-reply-to', 'references', 'date', 'message-id', 'content-type', 'mime-version' )
>> for h in mail.keys():
>> if h.lower() not in keep_headers:
>> del mail[ h ]
>> return sha256( mail.as_string() ).hexdigest()
>>
>
> W obecnych Pythonach możesz stosować konstrukcję (automagicznie zamknie uchwyt):
>
> def calculate_hash(filename):
> with open(filename) as f:
> mail = .....
a to powyżej nie zamknie uchwytu po wyjściu z funkcji?
> f = open(filename, 'r') to to samo co f = open(filename)
pewnie tak, ale akurat wolę explicite podawać tryb otwarcia pliku, takie
zboczenie.
>> def visit_fn( hash_dict, path, files ):
>> for i in [ 'new', 'tmp' ]:
>> if files.count ( i ) > 0:
>> files.remove( i )
>>
> Tu lepiej użyć tupli ('new', 'tmp').
czemu lepiej?
>> checksum = calculate_hash( full_path )
>> if not hash_dict.has_key( checksum ):
>> hash_dict[ checksum ] = list()
>> hash_dict[ checksum ].append( full_path )
>>
>> hash_dict = dict()
>>
>
> Alternatywnie (z tym, że trzeba uważać):
> hash_dict[checksum] = []
> hash_dict = {}
na co uważać?
> Oprócz konstrukcji: if not d.has_key(k):
> można też używać: if k not in d:
> Dla mnie ta druga jest czytelniejsza.
czy one są równoważne? w szczególności - czy ich wydajność będzie taka
sama jak d ma np. 10M elementów?
>> walk( sys.argv[1], visit_fn, hash_dict )
>>
>> for i in hash_dict.keys():
>> if len( hash_dict[i] ) == 1:
>> del hash_dict[i]
>>
>> for sha in hash_dict.keys():
>> print "# %s" % ( sha )
> Alternatywnie, po prostu: print '#', sha
dzięki za wszystkie uwagi.
depesz
--
The best thing about modern society is how easy it is to avoid contact with it.
http://depesz.com/
Re: Prośba o wytknięcie błędów
Author: hubert depesz lubaczewski
Date: Tue, 15 Nov 2011 14:17
Date: Tue, 15 Nov 2011 14:17
45 lines
2886 bytes
2886 bytes
On 2011-11-15, Adam Przybyla <adam@rybnik.pl> wrote:
>> def calculate_hash( filename ):
>> f = open( filename, 'r' )
>> mail = email.message_from_file( f )
>> keep_headers = ( 'subject', 'from', 'to', 'cc', 'in-reply-to', 'references', 'date', 'message-id', 'content-type', 'mime-version' )
>> for h in mail.keys():
>> if h.lower() not in keep_headers:
>> del mail[ h ]
>> return sha256( mail.as_string() ).hexdigest()
> ... mozna to napisac krocej:
> def calculate_hash( filename ):
> mail=email.message_from_file(open(filename))
> [mail.__delitem__(h) for h in mail.keys() if h.lower not in keep_headers]
> return sha256( mail.as_string() ).hexdigest()
ej, to ma być python a nie perl :)
a tak bardziej serio - wiem, że można wywalić część zmiennych (f), ale
nie za bardzo lubię robić kilka operacji na raz, w jednym poleceniu
(mówię o open/message_from_file).
co do mail.__delitem__ w []
z tym [] ( to się chyba nazywa list comprehension? )
mam problem koncepcyjny.
tzn. jak pisałem w perlu, to tam mamy podobny mechanizm, nazywa się map.
i podobnie jak ten trick z [] zwraca arraya/listę.
we wszystkich materiałach o stylu programowania piszą by nie używać map
ignorując rezultat (czyli np. nie przypisując go gdzieś, traktując go po
prostu jako jednoliniową pętlę).
i to mi się mocno wtłoczyło w mózg.
tak więc teraz patrząc na
[ ... for ... if ... ]
mam odruch odrzutny, bo to jest właśnie ignorowanie rezultatu.
może powinienem się przełamać.
dodatkowe pytanie - czy korzystanie bezpośrednio z __funkcji__ jest ok?
z tego co zrozumiałem, to są wewnętrznie używane funkcje które służą do
implementacji operatorów. dostęp do nich jest, ale wydawało mi się, że
używanie ich bezpośrednio jest jakieś "niekoszerne". myliłem się?
depesz
--
The best thing about modern society is how easy it is to avoid contact with it.
http://depesz.com/
Re: Prośba o wytknięcie błędów
Author: Stachu 'Dozzie' K.
Date: Tue, 15 Nov 2011 14:29
Date: Tue, 15 Nov 2011 14:29
48 lines
2683 bytes
2683 bytes
On 2011-11-15, hubert depesz lubaczewski <depesz@depesz.com> wrote:
>> def calculate_hash( filename ):
>> mail=email.message_from_file(open(filename))
>> [mail.__delitem__(h) for h in mail.keys() if h.lower not in keep_headers]
>> return sha256( mail.as_string() ).hexdigest()
[...]
> co do mail.__delitem__ w []
>
> z tym [] ( to się chyba nazywa list comprehension? )
> mam problem koncepcyjny.
> tzn. jak pisałem w perlu, to tam mamy podobny mechanizm, nazywa się map.
> i podobnie jak ten trick z [] zwraca arraya/listę.
Tutaj to nadużycie, podobnie jak w Perlu taki kod:
#v+
@a = (1, 2, 3, 4);
map { $_ *= 2 } @a;
#v-
> we wszystkich materiałach o stylu programowania piszą by nie używać map
> ignorując rezultat (czyli np. nie przypisując go gdzieś, traktując go po
> prostu jako jednoliniową pętlę).
> i to mi się mocno wtłoczyło w mózg.
> tak więc teraz patrząc na
> [ ... for ... if ... ]
> mam odruch odrzutny, bo to jest właśnie ignorowanie rezultatu.
> może powinienem się przełamać.
Moim zdaniem nie. Po to jest pętla for w Pythonie, żeby z niej
korzystać.
> dodatkowe pytanie - czy korzystanie bezpośrednio z __funkcji__ jest ok?
> z tego co zrozumiałem, to są wewnętrznie używane funkcje które służą do
> implementacji operatorów.
Jest OK, jeśli przesłaniasz albo implementujesz operator. Tutaj uważam
je za bezpodstawne.
> dostęp do nich jest, ale wydawało mi się, że
> używanie ich bezpośrednio jest jakieś "niekoszerne". myliłem się?
Widzisz, w Pythonie, wbrew temu co większość fanbojów mówi, można pisać
gówniany kod (tylko jest nieco trudniej). Widziałem nawet kiedyś zepsute
wcięcia w skrypcie pythonowym, który działał (sic!).
--
Secunia non olet.
Stanislaw Klekot
Re: Prośba o wytknięcie błędów
Author: Adam Przybyla
Date: Tue, 15 Nov 2011 15:55
Date: Tue, 15 Nov 2011 15:55
58 lines
3469 bytes
3469 bytes
hubert depesz lubaczewski <depesz@depesz.com> wrote: > On 2011-11-15, Adam Przybyla <adam@rybnik.pl> wrote: >>> def calculate_hash( filename ): >>> f = open( filename, 'r' ) >>> mail = email.message_from_file( f ) >>> keep_headers = ( 'subject', 'from', 'to', 'cc', 'in-reply-to', 'references', 'date', 'message-id', 'content-type', 'mime-version' ) >>> for h in mail.keys(): >>> if h.lower() not in keep_headers: >>> del mail[ h ] >>> return sha256( mail.as_string() ).hexdigest() >> ... mozna to napisac krocej: >> def calculate_hash( filename ): >> mail=email.message_from_file(open(filename)) >> [mail.__delitem__(h) for h in mail.keys() if h.lower not in keep_headers] >> return sha256( mail.as_string() ).hexdigest() > > ej, to ma być python a nie perl :) ... chcialem abys poczul sie bardziej swojsko;-)) > a tak bardziej serio - wiem, że można wywalić część zmiennych (f), ale > nie za bardzo lubię robić kilka operacji na raz, w jednym poleceniu > (mówię o open/message_from_file). > > co do mail.__delitem__ w [] > > z tym [] ( to się chyba nazywa list comprehension? ) > mam problem koncepcyjny. > tzn. jak pisałem w perlu, to tam mamy podobny mechanizm, nazywa się map. > i podobnie jak ten trick z [] zwraca arraya/listę. > we wszystkich materiałach o stylu programowania piszą by nie używać map > ignorując rezultat (czyli np. nie przypisując go gdzieś, traktując go po > prostu jako jednoliniową pętlę). > i to mi się mocno wtłoczyło w mózg. > tak więc teraz patrząc na > [ ... for ... if ... ] > mam odruch odrzutny, bo to jest właśnie ignorowanie rezultatu. > może powinienem się przełamać. ... ale tu maz zalete, bo mozesz pisac np. tak: >>> (x for x in xrange(10)) <generator object at 0x99ca34c> >>> >>> type([x for x in range(10)]) <type 'list'> >>> type((x for x in range(10))) <type 'generator'> >>> i zamiast tablicy zwraca ci ... generator tablicy - znaczit lazy evaluation;-) a map, reduce filter tez jest: map(lambda h: mail.__delitem__(h), filter(lambda h1: h1.lower not in keep_headers,mail.keys)) > > dodatkowe pytanie - czy korzystanie bezpośrednio z __funkcji__ jest ok? > z tego co zrozumiałem, to są wewnętrznie używane funkcje które służą do > implementacji operatorów. dostęp do nich jest, ale wydawało mi się, że > używanie ich bezpośrednio jest jakieś "niekoszerne". myliłem się? ... ale dziala;-) Z powazaniem Adam Przybyla
Re: Prośba o wytknięcie błędów
Author: Artur M. Piwko
Date: Fri, 18 Nov 2011 07:37
Date: Fri, 18 Nov 2011 07:37
59 lines
2574 bytes
2574 bytes
In the darkest hour on Tue, 15 Nov 2011 15:12:17 +0100,
hubert depesz lubaczewski <depesz@depesz.com> screamed:
>> W obecnych Pythonach możesz stosować konstrukcję (automagicznie zamknie uchwyt):
>>
>> def calculate_hash(filename):
>> with open(filename) as f:
>> mail = .....
>
> a to powyżej nie zamknie uchwytu po wyjściu z funkcji?
>
Zamknie. A podobno wolisz explicite podawaća w Twoim przykładzie brak
close(). ;-)
>>> def visit_fn( hash_dict, path, files ):
>>> for i in [ 'new', 'tmp' ]:
>>> if files.count ( i ) > 0:
>>> files.remove( i )
>>>
>> Tu lepiej użyć tupli ('new', 'tmp').
>
> czemu lepiej?
>
Tak, wiem, że [] to struktura, itp., ale w pętlach, gdzie nie muszę
"mutować" lubię dawać (). Własne przyzwyczajenie.
>> Alternatywnie (z tym, że trzeba uważać):
>> hash_dict[checksum] = []
>> hash_dict = {}
>
> na co uważać?
>
Żeby nie rozpędzić się i nie napisać kiedyś tak:
def fun(spam, eggs=[]):
eggs.append(spam)
print eggs
fun(1)
fun('abc')
>> Oprócz konstrukcji: if not d.has_key(k):
>> można też używać: if k not in d:
>> Dla mnie ta druga jest czytelniejsza.
>
> czy one są równoważne? w szczególności - czy ich wydajność będzie taka
> sama jak d ma np. 10M elementów?
>
Z tego co (blaaado) pamiętam druga była odrobinę szybsza. Ale mogę się
mylić.
--
[ Artur M. Piwko : Pipen : AMP29-RIPE : RLU:100918 : From == Trap! : SIG:235B ]
[ 08:33:22 user up 12990 days, 20:28, 1 user, load average: 0.01, 0.28, 0.12 ]
I haven't spoken to my wife in years. I didn't want to interrupt her.
Re: Prośba o wytknięcie błędów
Author: hubert depesz lubaczewski
Date: Fri, 18 Nov 2011 12:32
Date: Fri, 18 Nov 2011 12:32
27 lines
1710 bytes
1710 bytes
On 2011-11-18, Artur M. Piwko <milusi.pysiaczek@buziaczek.pl> wrote:
>>> Alternatywnie (z tym, że trzeba uważać):
>>> hash_dict[checksum] = []
>>> hash_dict = {}
>>
>> na co uważać?
>>
>
> Żeby nie rozpędzić się i nie napisać kiedyś tak:
>
> def fun(spam, eggs=[]):
> eggs.append(spam)
> print eggs
>
> fun(1)
> fun('abc')
ale z eggs=list() działa tak samo. w dodatku - czemu tak?
gdy patrzyłem na ten kod, bez uruchamiania, to uznałem, że eggs jest
przy każdym wywołaniu puste. czemu jego wartość została zachowana między
wywołaniami funkcji?
depesz
--
The best thing about modern society is how easy it is to avoid contact with it.
http://depesz.com/
Re: Prośba o wytknięcie błędów
Author: Stachu 'Dozzie' K.
Date: Fri, 18 Nov 2011 12:47
Date: Fri, 18 Nov 2011 12:47
25 lines
2315 bytes
2315 bytes
On 2011-11-18, hubert depesz lubaczewski <depesz@depesz.com> wrote:
>> def fun(spam, eggs=[]):
>> eggs.append(spam)
>> print eggs
>>
>> fun(1)
>> fun('abc')
>
> ale z eggs=list() działa tak samo. w dodatku - czemu tak?
> gdy patrzyłem na ten kod, bez uruchamiania, to uznałem, że eggs jest
> przy każdym wywołaniu puste. czemu jego wartość została zachowana między
> wywołaniami funkcji?
Jesteś przyzwyczajony z innych języków, że definicja funkcji to jest
sprawa czasu kompilacji. W Pythonie to nieprawda: funkcja jest
tworzona dopiero podczas pracy programu. W związku z tym powyższa
funkcja najpierw tworzy obiekt typu lista (który jest pusty), a potem
przywiązuje go jako argument domyślny do właśnie utworzonej funkcji.
Kolejne uruchomienia funkcji dostają ten sam obiekt (listę) jako wartość
domyślną, więc jeśli zmienisz obiekt, zmiana zostanie zachowana do
następnego uruchomienia.
--
Secunia non olet.
Stanislaw Klekot
Re: Prośba o wytknięcie błędów
Author: hubert depesz lubaczewski
Date: Fri, 18 Nov 2011 14:24
Date: Fri, 18 Nov 2011 14:24
20 lines
1892 bytes
1892 bytes
On 2011-11-18, Stachu 'Dozzie' K. <dozzie@go.eat.some.screws.spammer.invalid> wrote:
> Jesteś przyzwyczajony z innych języków, że definicja funkcji to jest
ciekawe jakich :)
> sprawa czasu kompilacji. W Pythonie to nieprawda: funkcja jest
> tworzona dopiero podczas pracy programu. W związku z tym powyższa
> funkcja najpierw tworzy obiekt typu lista (który jest pusty), a potem
> przywiązuje go jako argument domyślny do właśnie utworzonej funkcji.
> Kolejne uruchomienia funkcji dostają ten sam obiekt (listę) jako wartość
> domyślną, więc jeśli zmienisz obiekt, zmiana zostanie zachowana do
> następnego uruchomienia.
ok. a jak uzyskać efekt domyślnej pustej listy/dicta?
depesz
--
The best thing about modern society is how easy it is to avoid contact with it.
http://depesz.com/
Re: Prośba o wytknięcie błędów
Author: Jordan Szubert
Date: Fri, 18 Nov 2011 14:34
Date: Fri, 18 Nov 2011 14:34
44 lines
2325 bytes
2325 bytes
Dnia 18-11-2011 o 13:32:02 hubert depesz lubaczewski <depesz@depesz.com>
napisał(a):
> On 2011-11-18, Artur M. Piwko <milusi.pysiaczek@buziaczek.pl> wrote:
>>>> Alternatywnie (z tym, że trzeba uważać):
>>>> hash_dict[checksum] = []
>>>> hash_dict = {}
>>>
>>> na co uważać?
>>>
>>
>> Żeby nie rozpędzić się i nie napisać kiedyś tak:
>>
>> def fun(spam, eggs=[]):
>> eggs.append(spam)
>> print eggs
>>
>> fun(1)
>> fun('abc')
>
> ale z eggs=list() działa tak samo. w dodatku - czemu tak?
> gdy patrzyłem na ten kod, bez uruchamiania, to uznałem, że eggs jest
> przy każdym wywołaniu puste. czemu jego wartość została zachowana między
> wywołaniami funkcji?
w pythonie wyrazenia opisujace argumenty domyslne sa ewaluowane w czasie
tworzenia funkcji, a nie przed kazdym wywolaniem, wiec wszytkie wywolania
uzywajace argumentu domyslnego uzywaja tej samej instancji, a jest jest to
obietk modyfikowalny, to modyfikacjie nie znikaja magicznie
ale:
def fun(spam,eggs=[]):
eggs=eggs+[spam]
print(eggs)
fun(1)
fun('abc')
ale tutaj nie modyfikujemy obkietu siedzacego pod nazwa eggs, a podpinamy
pod ta nazwe inny obiekt
--
Jordan Szubert
Re: Prośba o wytknięcie błędów
Author: Stachu 'Dozzie' K.
Date: Fri, 18 Nov 2011 14:43
Date: Fri, 18 Nov 2011 14:43
31 lines
2467 bytes
2467 bytes
On 2011-11-18, hubert depesz lubaczewski <depesz@depesz.com> wrote:
> On 2011-11-18, Stachu 'Dozzie' K. <dozzie@go.eat.some.screws.spammer.invalid> wrote:
>> Jesteś przyzwyczajony z innych języków, że definicja funkcji to jest
>
> ciekawe jakich :)
Choćby Perl. Wprawdzie tam nie ma czegoś takiego jak wartość domyślna
dla parametru, ale przynajmniej funkcje są tworzone podczas kompilacji.
>> sprawa czasu kompilacji. W Pythonie to nieprawda: funkcja jest
>> tworzona dopiero podczas pracy programu. W związku z tym powyższa
>> funkcja najpierw tworzy obiekt typu lista (który jest pusty), a potem
>> przywiązuje go jako argument domyślny do właśnie utworzonej funkcji.
>> Kolejne uruchomienia funkcji dostają ten sam obiekt (listę) jako wartość
>> domyślną, więc jeśli zmienisz obiekt, zmiana zostanie zachowana do
>> następnego uruchomienia.
>
> ok. a jak uzyskać efekt domyślnej pustej listy/dicta?
Zgadnij :)
#v+
def foo(arg = None):
if arg is None:
arg = []
# ...
#v-
--
Secunia non olet.
Stanislaw Klekot
Re: Prośba o wytknięcie błędów
Author: William Bonawentura
Date: Mon, 04 Jun 2012 05:15
Date: Mon, 04 Jun 2012 05:15
16 lines
1600 bytes
1600 bytes
> moglisbyście mi powiedzieć co zrobiłem nie po pythonowemu, lub co można
> zrobić lepiej/bardziej pythonowo.
def calculate_hash( filename ):
f = open( filename, 'r' )
mail = email.message_from_file( f )
Metoda biznesowa (liczenie hasha) nie powinna realizować dostępu do danych.
Czyli jej parametrem powinien być mail a nie filename. Gdzieś na zewnątrz,
komponent aplikacyjny, dokona tej integracji:
with open( filename ) as f:
mail = email.message_from_file( f )
hash = email_calculator.calculate_hash( mail )
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