🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Thread View: pl.comp.lang.python
8 messages
8 total messages Started by Slawomir Piasecki Thu, 28 Jan 2010 12:07
odwolywanie sie w funckji do tej samej funkcji
#27273
Author: Slawomir Piasecki
Date: Thu, 28 Jan 2010 12:07
83 lines
3941 bytes
czesc wszystkim

mam problem z pythonem

w skrocie mam wlasna funkcje w ktorej mam petle i w tejze petli
odwoluje sie do tej samej funkcji, i mam problem z zmienna nr

[code]
def bRun(val, name, bf, res, bfpt, info, mlt, pr, nr = {0:1}, check =
False):
  solutions = {}
  new, cz = runF(val, name, bf, res, check)
  solt = oneTab(new)
  lst = nr.keys()[-1]
  last = glMulti(nr)

  if solt["e"] > 0 and last < mlt:
    m = 1

    solutions[lst] = {"data" : solt, 'mlt' : last}
    tmp = newName(name, nr, True)

    if len(nr) == 1:
      fwrite("dane.%s.dat" % tmp, info, {"dat":val,"UZR" : "{5: %s}" %
bf})

    else:
      fwrite("dane.%s.dat" % tmp, info, {'ISW' : -1, 'NTST' : 1000,
'IRS' : 1, 'UZR' : '{5 : %s}' % bf})

    perLoop = periodInfo(cz, bfpt, last)

    if len(perLoop) > 0:
      solutions[lst]["next"] = {}
      step = 1

      for i in perLoop:
        var = getSelectData(val, i)
        nr[lst + 1] = perLoop[i][0]
        last = glMulti(nr)

        if last < mlt and lst < 3:
          tmp = newName(name, nr)

          multiPerVar(var, pr, tmp, last)
          tmpNr = nr
          solutions[lst]["next"][step] = bRun(val, tmp, bf, res, bfpt,
info, mlt, pr, tmpNr, "rtbp2")

        step += 1

      if len(solutions[lst]["next"]) == 0:
        del solutions[lst]["next"]

  return solutions
[/code]

nie wiem jak to porzadnie wytlumaczyc, wiec sprobuje to wytlumaczyc na
tym przykladzie

wiec zalozmy po pierwszym wywolaniu zmienna perLoop ma dwie zmienne,
wiec petla sie wykona dwukrotnie, pierwsze wykonanie oznaczmy A a
drugie B, teraz wykonujac A znajdujemy ze zmienna nr ma postac, {0:
1], i nowe perLoop ma 3 zmienne ktore wykonujemy i tam zmienna ma
postac {0:1, 1:x}
i tu spelniaja sie warunki ktore uniemozliwiaja mi kolejne wywolanie
funkcji bRun wiec wracam do elementu B
ale niestety tutaj napotykam problem, gdyz wg. mnie zmienna nr powinna
miec teraz postac {0:2} natomiast to co otrzymuje to jest {0:2, 1:x}
jesce zanim znajde czy nowy perLoop ma jakies elementy,

z tego wnioskuje ze zmienna nr nie jest zmienna lokalna, czego
zupelnie nie rozumiem, gdyz myslalem
ze zmienne w funkcji sa lokalne, a tu widze na swoim przykladzie ze
tak nie jest, bo gdyby tak bylo to zmienna nr po wykonaniu A i
kolejnych wywolaniach bRun powinna miec postac {0:1,1:x,....} ale w
momencie jak startuje z B powinna miec postac {0:2}

mam nadzieje ze mnie ktos zrozumie i wytlumaczy mi gdzie zle mysle,
lub gdzie popelnilem blad
dzieki za wyrozumialosc, pewnie cos tu bedzie nie zrozumiale wiec
pytajcie moze
uda mi sie jakos inaczej rozjasnic o co mi chodzi
Re: odwolywanie sie w funckji do tej samej funkcji
#27274
Author: Bart Ogryczak
Date: Thu, 28 Jan 2010 14:22
38 lines
2428 bytes
On Jan 28, 1:07 pm, Slawomir Piasecki <piase...@gmail.com> wrote:
> czesc wszystkim
>
> mam problem z pythonem

Dżizas, startujesz w jakimś konkursie na obfuskowanie kodu?

> z tego wnioskuje ze zmienna nr nie jest zmienna lokalna, czego
> zupelnie nie rozumiem, gdyz myslalem
> ze zmienne w funkcji sa lokalne, a tu widze na swoim przykladzie ze
> tak nie jest, bo gdyby tak bylo to zmienna nr po wykonaniu A i
> kolejnych wywolaniach bRun powinna miec postac {0:1,1:x,....} ale w
> momencie jak startuje z B powinna miec postac {0:2}

Domyślne wartości w deklaracji funkcji są ewaluowane *raz*, podczas
parsowania funkcji.
Domyślna wartość, która jest typem mutowalnym będzie wskazywała na *tę
samą instancję*, a nie tworzyła nową.

def f(x=[]):
   x.append(len(x))
   print x

f()
f()
f()

Standardowym trikiem jest np.
def f(x=None):
  if(x is None):
    x = []


btw. inny przykład niezbyt mądrego użycia typu mutowalnego

x = [[]]*10
x[0].append('a')
print x
Re: odwolywanie sie w funckji do tej samej funkcji
#27280
Author: Sebastian Kaliszewski
Date: Thu, 28 Jan 2010 14:54
171 lines
6468 bytes
Slawomir Piasecki wrote:
> czesc wszystkim
> 
> mam problem z pythonem
> 
> w skrocie mam wlasna funkcje w ktorej mam petle i w tejze petli
> odwoluje sie do tej samej funkcji, i mam problem z zmienna nr
> 
> [code]
> def bRun(val, name, bf, res, bfpt, info, mlt, pr, nr = {0:1}, check =
> False):
>   solutions = {}
>   new, cz = runF(val, name, bf, res, check)
>   solt = oneTab(new)
>   lst = nr.keys()[-1]
>   last = glMulti(nr)
> 
>   if solt["e"] > 0 and last < mlt:
>     m = 1
> 
>     solutions[lst] = {"data" : solt, 'mlt' : last}
>     tmp = newName(name, nr, True)
> 
>     if len(nr) == 1:
>       fwrite("dane.%s.dat" % tmp, info, {"dat":val,"UZR" : "{5: %s}" %
> bf})
> 
>     else:
>       fwrite("dane.%s.dat" % tmp, info, {'ISW' : -1, 'NTST' : 1000,
> 'IRS' : 1, 'UZR' : '{5 : %s}' % bf})
> 
>     perLoop = periodInfo(cz, bfpt, last)
> 
>     if len(perLoop) > 0:
>       solutions[lst]["next"] = {}
>       step = 1
> 
>       for i in perLoop:
>         var = getSelectData(val, i)
>         nr[lst + 1] = perLoop[i][0]
>         last = glMulti(nr)
> 
>         if last < mlt and lst < 3:
>           tmp = newName(name, nr)
> 
>           multiPerVar(var, pr, tmp, last)
>           tmpNr = nr
>           solutions[lst]["next"][step] = bRun(val, tmp, bf, res, bfpt,
> info, mlt, pr, tmpNr, "rtbp2")
> 
>         step += 1
> 
>       if len(solutions[lst]["next"]) == 0:
>         del solutions[lst]["next"]
> 
>   return solutions
> [/code]
> 
> nie wiem jak to porzadnie wytlumaczyc, wiec sprobuje to wytlumaczyc na
> tym przykladzie
> 
> wiec zalozmy po pierwszym wywolaniu zmienna perLoop ma dwie zmienne,
> wiec petla sie wykona dwukrotnie, pierwsze wykonanie oznaczmy A a
> drugie B, teraz wykonujac A znajdujemy ze zmienna nr ma postac, {0:
> 1], i nowe perLoop ma 3 zmienne ktore wykonujemy i tam zmienna ma
> postac {0:1, 1:x}
> i tu spelniaja sie warunki ktore uniemozliwiaja mi kolejne wywolanie
> funkcji bRun wiec wracam do elementu B
> ale niestety tutaj napotykam problem, gdyz wg. mnie zmienna nr powinna
> miec teraz postac {0:2} natomiast to co otrzymuje to jest {0:2, 1:x}
> jesce zanim znajde czy nowy perLoop ma jakies elementy,
> 
> z tego wnioskuje ze zmienna nr nie jest zmienna lokalna, czego
> zupelnie nie rozumiem, gdyz myslalem
> ze zmienne w funkcji sa lokalne, a tu widze na swoim przykladzie ze
> tak nie jest, bo gdyby tak bylo to zmienna nr po wykonaniu A i
> kolejnych wywolaniach bRun powinna miec postac {0:1,1:x,....} ale w
> momencie jak startuje z B powinna miec postac {0:2}
> 
> mam nadzieje ze mnie ktos zrozumie i wytlumaczy mi gdzie zle mysle,
> lub gdzie popelnilem blad
> dzieki za wyrozumialosc, pewnie cos tu bedzie nie zrozumiale wiec
> pytajcie moze
> uda mi sie jakos inaczej rozjasnic o co mi chodzi

W Pythonie nazwy obiektów to nie to co obiekty. W powyższym kodzie nr i 
tmpNr to różne nazwy tego samego obiektu.  Jak chcesz mieć inny obiekt 
to go musisz gdzieś utworzyć.

Zamiast bezskutecznego kombinowania z tmpNr zmień wołanie

solutions[lst]["next"][step] = bRun(val, tmp, bf, res, bfpt, info, mlt, 
pr, tmpNr, "rtbp2")

na:

solutions[lst]["next"][step] = bRun(val, tmp, bf, res, bfpt, info, mlt, 
pr, dict(nr), "rtbp2")




Ogólnie:

Generalnie wyróżnia się 4 (w miarę typowych) semantyk (sposobów) 
gorliwego (tj. nie leniwego) przekazywania parametrów...

Zakładamy że mamy funkcję:

fun(a, b, t, u):
   print a, b, t[0], u[1]
   tmp = a
   a = b
   b = tmp
   t[0] = 13
   u[1] = 19

oraz kod ją wołający

a = 10
b = 20
tab = [7, 5]
fun(a, b, tab, tab)
print a, b, tab[0], tab[1]

1. Przez wartość -- lokalnie tworzone są nowe zmienne do których 
kopiowane są przekazane w wołaniu wartości  -- ww. kod wypisze :
10 20 7 5
10 20 7 5

2. Przez zmienną -- w parametrze przekazuje się (referencję na) zmienną, 
niejako tworzy się alias przekazywanej zmiennej, wszelkie zmiany 
parametru, łącznie z przypisaniem są widoczne na zewnątrz funkcji -- ww. 
kod wypisze:
10 20 7 5
20 10 13 19

3. Przez kopię -- lokalnie tworzone są nowe zmienne do których kopiowane 
są przekazane w wołaniu zmienne (czyli tak w 1.), ale na zakończenie 
działania funkcji  wartości tych lokalnych zmiennych utworzonych wg 
parametrów są kopiowane z powrotem do przekazanych w wołaniu zmiennych; 
kłopot taki że jak się przekaże 2 razy tę samą zmienną to mogą być 
"zabawne" efekty -- ww. kod wypisze:
10 20 7 5
20 10 7 19
lub
10 20 7 5
20 10 13 5
zależnie od kolejności kopiowania parametrów na zakończenie funkcji

4. Przez obiekt -- odróżniamy nazwę zmiennej (obiektu) od jej wartości, 
lokalnie powstaje nowa nazwa, dowiązane do nowego obiektu, czyli 
podobnie do 2. ale lokalne przypisanie nie jest widoczne na zewnątrz, 
tylko lokalna mutacja jest -- ww. kod wypisze:
10 20 7 5
10 20 13 19



Python używa właśnie 4 sposobu


Podsumowując:
zakłądałeś, że Python używa 1. sposobu a on używa 4.

pzdr
\SK
-- 
"Never underestimate the power of human stupidity" -- L. Lang
-- 
http://www.tajga.org -- (some photos from my travels)
Re: odwolywanie sie w funckji do tej samej funkcji
#27275
Author: Łukasz Rekucki
Date: Thu, 28 Jan 2010 16:06
70 lines
4555 bytes
On Jan 28, 1:07 pm, Slawomir Piasecki <piase...@gmail.com> wrote:
> czesc wszystkim
>
> mam problem z pythonem
>
> w skrocie mam wlasna funkcje w ktorej mam petle i w tejze petli
> odwoluje sie do tej samej funkcji, i mam problem z zmienna nr

<snip>
Kod wrzuciłem sobie na http://gist.github.com/288844 żeby łatwiej było
go przeczytać.

> nie wiem jak to porzadnie wytlumaczyc, wiec sprobuje to wytlumaczyc na
> tym przykladzie
>
> wiec zalozmy po pierwszym wywolaniu zmienna perLoop ma dwie zmienne,
Zakładam, że chodzi ci o listę, która ma dwa elementy (wyrażenie
"zmienna ma dwie zmienne" nie opisuję dobrze sytuacji).

> wiec petla sie wykona dwukrotnie, pierwsze wykonanie oznaczmy A a
> drugie B, teraz wykonujac A znajdujemy ze zmienna nr ma postac, {0:
> 1}, i nowe perLoop ma 3 zmienne ktore wykonujemy i tam zmienna ma
> postac {0:1, 1:x}
Nigdzie pomiędzy liniami 23-34 nie widzę, żeby perLoop się jakkolwiek
zmieniało, więc nie wiem skąd miało by mieć nagle 3 elementy.

> i tu spelniaja sie warunki ktore uniemozliwiaja mi kolejne wywolanie
> funkcji bRun wiec wracam do elementu B
> ale niestety tutaj napotykam problem, gdyz wg. mnie zmienna nr powinna
> miec teraz postac {0:2} natomiast to co otrzymuje to jest {0:2, 1:x}
> jesce zanim znajde czy nowy perLoop ma jakies elementy,
Jeśli przekazałeś słownik, który jest pod zmienną nr, do jakieś
funkcji, to ta funkcja może zmienić ten słownik. Nie może zmienić
twojej zmiennej - nr nadal będzie wskazywać na ten sam słownik, ale to
nie znaczy, że ten słownik się nie zmieni. Mówiąc bardziej fachowo: w
Pythonie zmienne są tylko nazwami wskazującymi na obiekty, a
przekazywanie argumentów odbywa się przez przekazanie kopii wskaźnika,
a nie kopii całego obiektu.

Drugi aspekt, to taki, że argumenty domyślne są tworzone tylko raz.
Łatwo prowadzi to do pułapki, jeśli się tam poda obiekt, który może
zmienić stan. Na przykład:

def dodaj_5(lista=[]):
    lista.append(5)
    return lista

print dodaj_5() # [5]
print dodaj_5() # [5,5]

> z tego wnioskuje ze zmienna nr nie jest zmienna lokalna, czego
> zupelnie nie rozumiem, gdyz myslalem
> ze zmienne w funkcji sa lokalne, a tu widze na swoim przykladzie ze
> tak nie jest, bo gdyby tak bylo to zmienna nr po wykonaniu A i
> kolejnych wywolaniach bRun powinna miec postac {0:1,1:x,....} ale w
> momencie jak startuje z B powinna miec postac {0:2}
>
> mam nadzieje ze mnie ktos zrozumie i wytlumaczy mi gdzie zle mysle,
> lub gdzie popelnilem blad
> dzieki za wyrozumialosc, pewnie cos tu bedzie nie zrozumiale wiec
> pytajcie moze
> uda mi sie jakos inaczej rozjasnic o co mi chodzi

Twój kod ogólnie jest bardzo chaotyczny, a nazwy zmiennych i funkcji
bardzo mało informujące. Funkcja, która przymuję 8 argumentów, to nie
funkcja tylko zgroza - nie wierze, że pamiętasz ich kolejność bez
patrzenia na definicję. Znalazło by się też kilka innych uwag, jak
np.  lst = nr.keys()[-1] <- to wygląda jakbyś zakładał, że da ci to
ostatnio wstawiony klucz albo coś w tym stylu, podczas gdy kolejność
kluczy w słowniku jest *nieustalona*.
Re: odwolywanie sie w funckji do tej samej funkcji
#27276
Author: Slawomir Piasecki
Date: Mon, 01 Feb 2010 09:13
40 lines
3278 bytes
> Jeśli przekazałeś słownik, który jest pod zmienną nr, do jakieś
> funkcji, to ta funkcja może zmienić ten słownik. Nie może zmienić
> twojej zmiennej - nr nadal będzie wskazywać na ten sam słownik, ale to
> nie znaczy, że ten słownik się nie zmieni. Mówiąc bardziej fachowo: w
> Pythonie zmienne są tylko nazwami wskazującymi na obiekty, a
> przekazywanie argumentów odbywa się przez przekazanie kopii wskaźnika,
> a nie kopii całego obiektu.
>
> Drugi aspekt, to taki, że argumenty domyślne są tworzone tylko raz.
> Łatwo prowadzi to do pułapki, jeśli się tam poda obiekt, który może
> zmienić stan. Na przykład:
>
> def dodaj_5(lista=[]):
>     lista.append(5)
>     return lista
>
> print dodaj_5() # [5]
> print dodaj_5() # [5,5]

ok, to w takim razie zeby po wykonaniu sie bRun z linii 31, slownik nr
nie zawieral elementow ktore zostaly zapisane w bRun
to co musialbym zrobic? wlasnie myslalem ze moze wprowadzenie nowej
zmiennej tmpNr sprawi, ze po wykonaniu bRun slownik
nr bedzie mial tyle elementow co przed wywolaniem bRun

> Twój kod ogólnie jest bardzo chaotyczny, a nazwy zmiennych i funkcji
> bardzo mało informujące. Funkcja, która przymuję 8 argumentów, to nie
> funkcja tylko zgroza - nie wierze, że pamiętasz ich kolejność bez
> patrzenia na definicję. Znalazło by się też kilka innych uwag, jak
> np.  lst = nr.keys()[-1] <- to wygląda jakbyś zakładał, że da ci to
> ostatnio wstawiony klucz albo coś w tym stylu, podczas gdy kolejność
> kluczy w słowniku jest *nieustalona*.

no oczywiscie ze musze sprawdzac w definicji kolejnosc, ale co mam
zrobic, skoro tak duzo zmiennych potrzebuje,
moge wprawdzie, w definicji bRun za kazdym razem jak ja wywoluje
obliczac te dane, ale to chyba szkoda czasu

acha, czyli nie da sie wyciagnac ostatniego wstawionego klucza?
Re: odwolywanie sie w funckji do tej samej funkcji
#27277
Author: Bart Ogryczak
Date: Mon, 01 Feb 2010 12:33
14 lines
2212 bytes
On Feb 1, 10:13 am, Slawomir Piasecki <piase...@gmail.com> wrote:

> > Twój kod ogólnie jest bardzo chaotyczny, a nazwy zmiennych i funkcji
> > bardzo mało informujące. Funkcja, która przymuję 8 argumentów, to nie
> > funkcja tylko zgroza - nie wierze, że pamiętasz ich kolejność bez
> > patrzenia na definicję. Znalazło by się też kilka innych uwag, jak
> > np.  lst = nr.keys()[-1] <- to wygląda jakbyś zakładał, że da ci to
> > ostatnio wstawiony klucz albo coś w tym stylu, podczas gdy kolejność
> > kluczy w słowniku jest *nieustalona*.

> acha, czyli nie da sie wyciagnac ostatniego wstawionego klucza?

Nie, bez dodatkowej zmiennej nie da się. Słownik jest tablicą
haszującą.
Re: odwolywanie sie w funckji do tej samej funkcji
#27278
Author: Slawomir Piasecki
Date: Wed, 03 Feb 2010 11:44
12 lines
1981 bytes
to jak powinienem sie za to zabrac, zeby po wywolaniu i wykonaniu sie
funkcji bRun
takie obiekty jak "nr" czy "step", posiadaly informacje takie jak
przed wywolaniem funkcji,
bo jesli dobrze zrozumialem, jesli wywolam funkcje bRun i wewnatrz tej
funkcji wywolam ja raz jeszcze (step = 1)
i tam zapisze, ze step = 3, to po wykonaniu tej fukcji (tej drugiej) i
powrocie do pierwszej funkcji, bede mial obiekt
step = 3 mimo, ze przed drugim wywolaniem byl rowny 1

pozdrawiam
p.s.
Re: odwolywanie sie w funckji do tej samej funkcji
#27279
Author: Sebastian Kaliszewski
Date: Wed, 03 Feb 2010 14:24
76 lines
3327 bytes
Slawomir Piasecki wrote:
> to jak powinienem sie za to zabrac, zeby po wywolaniu i wykonaniu sie
> funkcji bRun
> takie obiekty jak "nr" czy "step", posiadaly informacje takie jak
> przed wywolaniem funkcji,
> bo jesli dobrze zrozumialem, jesli wywolam funkcje bRun i wewnatrz tej
> funkcji wywolam ja raz jeszcze (step = 1)
> i tam zapisze, ze step = 3, to po wykonaniu tej fukcji (tej drugiej) i
> powrocie do pierwszej funkcji, bede mial obiekt
> step = 3 mimo, ze przed drugim wywolaniem byl rowny 1

Źle zrozumiałeś.

Przypisanie nie będzie widoczne na zewnątrz. Ciągle mylis zobiekt i jego 
nazwę, przypisanie to jest "podpięcie" nazwy pod obiekt. Na zewnątrz za 
to widoczne będą zmiany w przekazanych obiektach. Czyli jak masz

def foo(lista=[]):
   lista.append('bar')
   print lista

print 'pierwsze:'
foo()
print 'drugie:'
foo()
print 'trzecie:'
foo([])
print 'czwarte:'
foo()

to wynikiem będzie...
pierwsze:
['bar']
drugie:
['bar', 'bar']
trzecie:
['bar']
czwarte:
['bar', 'bar', 'bar']


Natomiast wynik tego...
def foo(lista=[]):
   lista = ['baz']
   print lista

print 'pierwsze:'
foo()
print 'drugie:'
foo()
print 'trzecie:'
foo([])
print 'czwarte:'
foo()

będzie...
pierwsze:
['baz']
drugie:
['baz']
trzecie:
['baz']
czwarte:
['baz']


Bo w pierwszym przypadku zmieniamy obiekt z listą a w drugim przed 
zmianą pod nazwę lista podpinamy nowy obiekt stary (ten z parametru) 
zostawiając w spokoju.

pzdr
\SK
-- 
'Never underestimate the power of human stupidity' -- L. Lang
-- 
http://www.tajga.org -- (some photos from my travels)
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