Thread View: pl.comp.lang.python
25 messages
25 total messages
Started by Michal M
Tue, 15 Dec 2009 21:39
Python i importowanie
Author: Michal M
Date: Tue, 15 Dec 2009 21:39
Date: Tue, 15 Dec 2009 21:39
42 lines
2481 bytes
2481 bytes
Witam
Ostatnio się bardzo zdziwiłem faktem jak działa importowanie w
Pythonie. Taki przykład:
module1.py
------------------------
class Test1(object):
my_var = 'a'
@staticmethod
def change():
Test1.my_var = 'b'
=============
module2.py
-----------------------
import module1
module1.Test1.change()
print module1.Test1.my_var
============
module3.py
----------------------
from module1 import Test1
print Test1.my_var
===========
Zakładając, że wszystko się wykonuje w jednym programie. Najpierw
module2 ustawia zmienną instancji klasy Test1 na wartość 'b'.
Tak więc w module3 spodziewałem się ujrzeć 'b', a jest 'a'.
Wygląda to tak, że from .... import rzeczywiście importuje do swojej
przestrzeni czyli hmm... tak jakby robił kopię obiektu.
Czytając wszelakie materiały nie widziałem (lub przegapiłem, lub nie
zrozumiałem) wzmiankę o takim zachowaniu.
Teraz pytanie, co zrobić, aby w module3 mieć dostęp do TEGO SAMEGO
obiektu Test1 co w module1 i w module2 ale nie musieć pisać za każdym
razem module1.Test1.my_var.
Pozdrawiam
Michał
Re: Python i importowanie
Author: Łukasz Rekucki
Date: Tue, 15 Dec 2009 23:15
Date: Tue, 15 Dec 2009 23:15
52 lines
3020 bytes
3020 bytes
On Dec 15, 10:39 pm, Michal M <mier...@swietochlowice.org> wrote: > Witam > > Ostatnio się bardzo zdziwiłem faktem jak działa importowanie w > Pythonie. Taki przykład: > > module1.py > ------------------------ > class Test1(object): > my_var = 'a' > > @staticmethod > def change(): > Test1.my_var = 'b' > ============= > module2.py > ----------------------- > import module1 > > module1.Test1.change() > print module1.Test1.my_var > ============ > module3.py > ---------------------- > from module1 import Test1 > > print Test1.my_var > =========== > > Zakładając, że wszystko się wykonuje w jednym programie. Ok, ale co jest w tym programie, bo liczy się kolejność importowania tych modułów. > Najpierw module2 ustawia zmienną instancji klasy Test1 na wartość 'b'. > Tak więc w module3 spodziewałem się ujrzeć 'b', a jest 'a'. > Wygląda to tak, że from .... import rzeczywiście importuje do swojej > przestrzeni czyli hmm... tak jakby robił kopię obiektu. Nie. Import .. from .. jedynie dodaje do słownika odpowiednie nazwy, które prowadzą do tych samych obiektów. Z tego co pamiętam, istnieje sposób żeby python zaimportował to samo 2 razy, ale nie jest to aż takie proste. Moduł ten musiałby być dostępny pod dwoma różnymi nazwami. > Czytając wszelakie materiały nie widziałem (lub przegapiłem, lub nie > zrozumiałem) wzmiankę o takim zachowaniu. > > Teraz pytanie, co zrobić, aby w module3 mieć dostęp do TEGO SAMEGO > obiektu Test1 co w module1 i w module2 ale nie musieć pisać za każdym > razem module1.Test1.my_var. > > Pozdrawiam > Michał
Re: Python i importowanie
Author: Rob Wolfe
Date: Wed, 16 Dec 2009 09:48
Date: Wed, 16 Dec 2009 09:48
54 lines
2665 bytes
2665 bytes
Michal M napisał(a): > Witam > > Ostatnio się bardzo zdziwiłem faktem jak działa importowanie w > Pythonie. Taki przykład: > > module1.py > ------------------------ > class Test1(object): > my_var = 'a' > > @staticmethod > def change(): > Test1.my_var = 'b' > ============= > module2.py > ----------------------- > import module1 > > module1.Test1.change() > print module1.Test1.my_var > ============ > module3.py > ---------------------- > from module1 import Test1 > > print Test1.my_var > =========== > > Zakładając, że wszystko się wykonuje w jednym programie. Najpierw > module2 ustawia zmienną instancji klasy Test1 na wartość 'b'. > Tak więc w module3 spodziewałem się ujrzeć 'b', a jest 'a'. > Wygląda to tak, że from .... import rzeczywiście importuje do swojej > przestrzeni czyli hmm... tak jakby robił kopię obiektu. > Czytając wszelakie materiały nie widziałem (lub przegapiłem, lub nie > zrozumiałem) wzmiankę o takim zachowaniu. Twierdzisz, ze masz np. program `main.py` postaci: import module2 import module3 i raz widzisz 'a' a raz 'b'? > > Teraz pytanie, co zrobić, aby w module3 mieć dostęp do TEGO SAMEGO > obiektu Test1 co w module1 i w module2 ale nie musieć pisać za każdym > razem module1.Test1.my_var. To jest i musi byc ten sam obiekt, o czym mozesz sie latwo przekonac wyswietlajac sobie wszedzie "id(Test1)". RW
Re: Python i importowanie
Author: silver
Date: Wed, 16 Dec 2009 10:23
Date: Wed, 16 Dec 2009 10:23
31 lines
2008 bytes
2008 bytes
W dniu 16.12.2009 10:48, Rob Wolfe pisze: > > > > Twierdzisz, ze masz np. program `main.py` postaci: > import module2 > import module3 > > i raz widzisz 'a' a raz 'b'? > Ja zrozumiałem że robi tak: 1. Pisze program module1.py i tworzy tam jakąś zmienną 2. Tworzy program module2.py w którym importuje module1.py 3. W programie module2.py zmienia zmienną w module1.py 4. W programie module3.py importuje module2.py i próbuje odczytać zmienną, którą z modułu module1.py i ma mieć taką wartość na jaką zmienił w module.2py Importy w pythonie działają podobnie do headerów w C++. To nie jest rzeczywisty import rezydującego gdzieś w pamięci modułu. To jest de facto rozszerzenie przestrzeni nazw do której masz dostęp. Obiekt klasy Test1 w module2.py jest zupełnie innym obiektem niż obiekt w module3.py Nic dziwnego, że masz inne wartości. Aby zrobić to co ty chcesz musiałbyś się zaciekawić komunikacją międzyprocesową. Zajrzyj do modułu multiprocessing -- Pozdrawiam, silver
Re: Python i importowanie
Author: silver
Date: Wed, 16 Dec 2009 10:25
Date: Wed, 16 Dec 2009 10:25
31 lines
2026 bytes
2026 bytes
W dniu 16.12.2009 10:48, Rob Wolfe pisze: > > > > Twierdzisz, ze masz np. program `main.py` postaci: > import module2 > import module3 > > i raz widzisz 'a' a raz 'b'? > Ja zrozumiałem że robi tak: 1. Pisze program module1.py i tworzy tam jakąś zmienną 2. Tworzy program module2.py w którym importuje module1.py 3. W programie module2.py zmienia zmienną w module1.py 4. W programie module3.py importuje module2.py i próbuje odczytać zmienną, którą zmienił w module module1.py i ma mieć taką wartość na jaką zmienił w module.2py Importy w pythonie działają podobnie do headerów w C++. To nie jest rzeczywisty import rezydującego gdzieś w pamięci modułu. To jest de facto rozszerzenie przestrzeni nazw do której masz dostęp. Obiekt klasy Test1 w module2.py jest zupełnie innym obiektem niż obiekt w module3.py Nic dziwnego, że masz inne wartości. Aby zrobić to co ty chcesz musiałbyś się zaciekawić komunikacją międzyprocesową. Zajrzyj do modułu multiprocessing -- Pozdrawiam, silver
Re: Python i importowanie
Author: Michal M
Date: Wed, 16 Dec 2009 10:54
Date: Wed, 16 Dec 2009 10:54
47 lines
2830 bytes
2830 bytes
Dziękuję za odpowiedzi. Mam wrażenie, że już sam nie wiem co robię. Robię to tak, jakbym pisał program w javie. Po prostu składa się z wielu plików ale nie uruchamiam ich oddzielnie tylko z jednego. Dodam, że gdybym zapisał module3 tak: module3.py ---------------------- import module1 print module1.Test1.my_var =========== To widzę to czego oczekiwałem, czyli 'b' Ale w takiej formie: module3.py ---------------------- from module1 import Test1 print Test1.my_var =========== Widzę 'a' Dlatego napisałem, że wygląda to tak, jakby obiekt on zaimportował do swojej przestrzeni nazw tak jakby kopiował (hmm.. że użyję terminologi z javy) klasę i tworzył jej instancję w przestrzeni nazw module3 który to zaimportował. Ale gdy importujemy cały moduł (import module1), wtedy klasa Test1 jest nadal w swojej przestrzeni gdzie ma atrybut my_var == 'b'. To jest oczywiście przykład obrazujący mój problem. Cały program jest trochę bardziej rozbudowany ale jeśli komuś to pomoże w odpowiedzi to mogę go gdzieś wystawić (jest dość krótki). Jeszcze tak przyszło mi na myśl. Mógłbym zaimportować cały moduł: import module1 i stworzyć zmienną: my_local = module1.Test1.my_var ale o ile w innych językach byłoby to jakieś ułatwinie to tutaj, ponieważ w każdej funkcji musiałbym dopisywać global my_local (ale mi wyszło.. ;) ) to nie wiele mi to da.
Re: Python i importowanie
Author: Michal M
Date: Wed, 16 Dec 2009 11:29
Date: Wed, 16 Dec 2009 11:29
21 lines
2053 bytes
2053 bytes
Dokładnie tak. Te trzy pliki działały jako jeden program (tak jak w javie) i jak wstawiałem do module3 from module1 import Lang to widziałem 'a', a jak wstawiałem import module1 to widziałem 'b'. Dlatego moje zdziwienie, bo wyglądało jakby te dwa nie powodowały tylko udostępnienia obiektu w przestrzeni nazw lokalnego modułu ale importowały (kopiowały) cały obiekt do tego modułu i tworzyły instancję. Wtedy obiekt Lang z module1 nie byłby tym samym co ten zaimportowany w module3. ALE... dzisiaj dziwnym trafem nie mogę odtworzyć tej sytuacji (ten sam kod, nie zmieniany) i wszystko działa jak Wy i Ja przewidujecie. Wobec tego wypada mi tylko przeprosić za zamieszanie i podziękować za odpowiedzi.
Re: Python i importowanie
Author: i0cus
Date: Wed, 16 Dec 2009 11:33
Date: Wed, 16 Dec 2009 11:33
38 lines
2821 bytes
2821 bytes
On 16 Gru, 11:23, silver <sil...@niematakiegoemaila.pl> wrote: > W dniu 16.12.2009 10:48, Rob Wolfe pisze: > > > > > Twierdzisz, ze masz np. program `main.py` postaci: > > import module2 > > import module3 > > > i raz widzisz 'a' a raz 'b'? > > Ja zrozumiałem że robi tak: > 1. Pisze program module1.py i tworzy tam jakąś zmienną > 2. Tworzy program module2.py w którym importuje module1.py > 3. W programie module2.py zmienia zmienną w module1.py > 4. W programie module3.py importuje module2.py i próbuje odczytać > zmienną, którą z modułu module1.py i ma mieć taką wartość na jaką > zmienił w module.2py I fajnie by było, ale OP napisał też: > Zakładając, że wszystko się wykonuje w jednym programie. No więc na moje oko dopasowałeś swoją wersję wyjaśnienia do błędu opisanego przez użytkownika. ;-) A mnie błąd użytkownika wygląda na (1) brak importu modułu 2, ew. (2) za kulisami dzieje się coś, co sprawia, że jednak dostaje świeże instancje Test1(). Python dość uparcie traktuje moduły jako singletony i wydaje mi się, że przedstawiony przykład zbytnio spłyca obraz sytuacji (a przede wszystkim nie oddaje opisanego zachowania -- jeśli zaimportowany zostanie moduł 2 i moduł 3, to wartości są 'b', gdyż moduł 1 jest ładowany jednokrotnie). > -- > Pozdrawiam, > silver
Re: Python i importowanie
Author: William Bonawentura
Date: Thu, 17 Dec 2009 07:41
Date: Thu, 17 Dec 2009 07:41
11 lines
1640 bytes
1640 bytes
Użytkownik "Michal M" <mmierzwa@tycowaterworks.pl> napisał w wiadomości news:52950de7-b700-40e0-964d-0bb7ab394964@x15g2000vbr.googlegroups.com... > ALE... dzisiaj dziwnym trafem nie mogę odtworzyć tej sytuacji (ten sam > kod, nie zmieniany) i wszystko działa jak Wy i Ja przewidujecie. Wobec > tego wypada mi tylko przeprosić za zamieszanie i podziękować za > odpowiedzi. Nie piszesz przypadkiem pod Unixem ? Efekt jaki opisujesz może być spowodowany sytuacją, gdy interpreter nie potrafi nadpisać lub utworzyć .pyc i każdy import powoduje parsowanie .py.
Re: Python i importowanie
Author: Rob Wolfe
Date: Thu, 17 Dec 2009 11:29
Date: Thu, 17 Dec 2009 11:29
17 lines
1634 bytes
1634 bytes
"William Bonawentura" <news@ipartners.pl> writes: > Użytkownik "Michal M" <mmierzwa@tycowaterworks.pl> napisał w > wiadomości > news:52950de7-b700-40e0-964d-0bb7ab394964@x15g2000vbr.googlegroups.com... >> ALE... dzisiaj dziwnym trafem nie mogę odtworzyć tej sytuacji (ten sam >> kod, nie zmieniany) i wszystko działa jak Wy i Ja przewidujecie. Wobec >> tego wypada mi tylko przeprosić za zamieszanie i podziękować za >> odpowiedzi. > > Nie piszesz przypadkiem pod Unixem ? Efekt jaki opisujesz może być > spowodowany sytuacją, gdy interpreter nie potrafi nadpisać lub > utworzyć .pyc i każdy import powoduje parsowanie .py. Nic podobnego. Kod i tak jest ładowany tylko raz. RW
Re: Python i importowanie
Author: Radomir Dopieralski
Date: Thu, 17 Dec 2009 17:52
Date: Thu, 17 Dec 2009 17:52
14 lines
1982 bytes
1982 bytes
At Wed, 16 Dec 2009 11:23:47 +0100, silver wrote: > Importy w pythonie działają podobnie do headerów w C++. To nie jest > rzeczywisty import rezydującego gdzieś w pamięci modułu. To jest de > facto rozszerzenie przestrzeni nazw do której masz dostęp. Obiekt klasy > Test1 w module2.py jest zupełnie innym obiektem niż obiekt w module3.py > Nic dziwnego, że masz inne wartości. To nie tak. Modul jest jeden - w obrebie jednego programu - zaimportowanie go wiele razy i tak zawsze zwroci ten sam obiekt, chyba ze sie zrobi jakies sztuczki z __import__. Include w C i pochodnych dziala kompletnie inaczej. Radomir Dopieralski, http://sheep.art.pl
Re: Python i importowanie
Author: Sebastian Kaliszewski
Date: Fri, 18 Dec 2009 10:11
Date: Fri, 18 Dec 2009 10:11
47 lines
2500 bytes
2500 bytes
silver wrote: > W dniu 16.12.2009 10:48, Rob Wolfe pisze: > > > > > > > > > Twierdzisz, ze masz np. program `main.py` postaci: > > import module2 > > import module3 > > > > i raz widzisz 'a' a raz 'b'? > > > Ja zrozumiałem że robi tak: > 1. Pisze program module1.py i tworzy tam jakąś zmienną > 2. Tworzy program module2.py w którym importuje module1.py > 3. W programie module2.py zmienia zmienną w module1.py > 4. W programie module3.py importuje module2.py i próbuje odczytać > zmienną, którą zmienił w module module1.py i ma mieć taką wartość na > jaką zmienił w module.2py > > Importy w pythonie działają podobnie do headerów w C++. Bzdura. > To nie jest > rzeczywisty import rezydującego gdzieś w pamięci modułu. To jest de > facto rozszerzenie przestrzeni nazw do której masz dostęp. Obiekt klasy > Test1 w module2.py jest zupełnie innym obiektem niż obiekt w module3.py > Nic dziwnego, że masz inne wartości. > > Aby zrobić to co ty chcesz musiałbyś się zaciekawić komunikacją > międzyprocesową. Co??? > Zajrzyj do modułu multiprocessing > Co ma piernik do wiatraka? pzdr \SK -- "Never underestimate the power of human stupidity" -- L. Lang -- http://www.tajga.org -- (some photos from my travels)
Re: Python i importowanie
Author: Sebastian Kaliszewski
Date: Fri, 18 Dec 2009 10:13
Date: Fri, 18 Dec 2009 10:13
27 lines
1893 bytes
1893 bytes
Michal M wrote: > Dokładnie tak. Te trzy pliki działały jako jeden program (tak jak w > javie) Co to znaczy tak jak w Javie? Pokaż całość -- co importuje co. Czyli co i gdzie importuje module2 oraz module3. [...] > ALE... dzisiaj dziwnym trafem nie mogę odtworzyć tej sytuacji (ten sam > kod, nie zmieniany) i wszystko działa jak Wy i Ja przewidujecie. Wobec > tego wypada mi tylko przeprosić za zamieszanie i podziękować za > odpowiedzi. Może jednak coś nie było tak samo. Np zapomniałeś zrobić "save" w edytorze (to się często zdarza) pzdr \SK -- "Never underestimate the power of human stupidity" -- L. Lang -- http://www.tajga.org -- (some photos from my travels)
Re: Python i importowanie
Author: Michal M
Date: Sun, 20 Dec 2009 21:10
Date: Sun, 20 Dec 2009 21:10
59 lines
2747 bytes
2747 bytes
Ok, ten sam problem się powtórzył. Tym razem podam dokładnie przykład.
module1.py
log = None
module2.py
class Log(object):
def __init__(self):
pass
def m(self):
print "ok"
module3.py
import module1
import module2
import module4
module1.log = module2.Log()
t = module4.Test()
t.use_m()
module4.py
from module1 import log
class Test(object):
def __init__(self):
pass
def use_m(self):
log.m()
Uruchamiam moduł 3. Ja to widzę tak:
1. importuje moduły 1, 2 i 3 (czyli udostępnia ich przestrzeń poprzez
nazwę modułu w module 3)
2. pod zmienną log w module 1 podstawia instancję klasy Log z modułu 2
3. Pod zmienną t podstawia instancję klasy Test z modułu 4 i próbuje
wykonać jej metodę use_m()
W tym miejscu otrzymuję błąd: AttributeError: 'NoneType' object has no
attribute 'm'
Teraz powiedzmy, że moduł 4 zmienię tak:
module4.py
import module1
class Test(object):
def __init__(self):
pass
def use_m(self):
module1.log.m()
Czyli wg mnie powinno być to samo, tyle że zamiast bezpośrednio do log
mam dostęp poprzez module1.log.
Zastanawiałem się, czy może samo log.m() nie widzi jako zmiennej
lokalnej i nie potrzeba dodać global log ale też nie pomaga.
Proszę o wyjaśnienie.
Pozdrawiam
Michał
Re: Python i importowanie
Author: marmarprog
Date: Sun, 20 Dec 2009 21:16
Date: Sun, 20 Dec 2009 21:16
47 lines
2810 bytes
2810 bytes
On 16 Gru, 11:25, silver <sil...@niematakiegoemaila.pl> wrote: > W dniu 16.12.2009 10:48, Rob Wolfe pisze: > > > > > > > > > Twierdzisz, ze masz np. program `main.py` postaci: > > import module2 > > import module3 > > > > i raz widzisz 'a' a raz 'b'? > > > Ja zrozumiałem że robi tak: > 1. Pisze program module1.py i tworzy tam jakąś zmienną > 2. Tworzy program module2.py w którym importuje module1.py > 3. W programie module2.py zmienia zmienną w module1.py > 4. W programie module3.py importuje module2.py i próbuje odczytać > zmienną, którą zmienił w module module1.py i ma mieć taką wartość na > jaką zmienił w module.2py > > Importy w pythonie działają podobnie do headerów w C++. To nie jest > rzeczywisty import rezydującego gdzieś w pamięci modułu. To jest de > facto rozszerzenie przestrzeni nazw do której masz dostęp. Obiekt klasy > Test1 w module2.py jest zupełnie innym obiektem niż obiekt w module3.py > Nic dziwnego, że masz inne wartości. > > Aby zrobić to co ty chcesz musiałbyś się zaciekawić komunikacją > międzyprocesową. Zajrzyj do modułu multiprocessing > > -- > Pozdrawiam, > silver Po wpisaniu takiego kodu import module2 import module3 from module1 import Test1 print Test1.my_var otrzymuje: b b b Wiec nie wiem w czym jest problem zwłaszcza tych bredni o nie rzeczywistym importowaniu.
Re: Python i importowanie
Author: marmarprog
Date: Sun, 20 Dec 2009 22:02
Date: Sun, 20 Dec 2009 22:02
97 lines
4139 bytes
4139 bytes
On 20 Gru, 22:10, Michal M <mmier...@tycowaterworks.pl> wrote:
> Ok, ten sam problem się powtórzył. Tym razem podam dokładnie przykład.
>
> module1.py
> log = None
>
> module2.py
> class Log(object):
> def __init__(self):
> pass
> def m(self):
> print "ok"
>
> module3.py
> import module1
> import module2
> import module4
>
> module1.log = module2.Log()
> t = module4.Test()
> t.use_m()
>
> module4.py
> from module1 import log
>
> class Test(object):
> def __init__(self):
> pass
> def use_m(self):
> log.m()
>
> Uruchamiam moduł 3. Ja to widzę tak:
> 1. importuje moduły 1, 2 i 3 (czyli udostępnia ich przestrzeń poprzez
> nazwę modułu w module 3)
> 2. pod zmienną log w module 1 podstawia instancję klasy Log z modułu 2
> 3. Pod zmienną t podstawia instancję klasy Test z modułu 4 i próbuje
> wykonać jej metodę use_m()
> W tym miejscu otrzymuję błąd: AttributeError: 'NoneType' object has no
> attribute 'm'
>
> Teraz powiedzmy, że moduł 4 zmienię tak:
>
> module4.py
> import module1
>
> class Test(object):
> def __init__(self):
> pass
> def use_m(self):
> module1.log.m()
>
> Czyli wg mnie powinno być to samo, tyle że zamiast bezpośrednio do log
> mam dostęp poprzez module1.log.
> Zastanawiałem się, czy może samo log.m() nie widzi jako zmiennej
> lokalnej i nie potrzeba dodać global log ale też nie pomaga.
> Proszę o wyjaśnienie.
>
> Pozdrawiam
> Michał
Python tak działa.
Zmienne można powiedzieć są etykietowane przez nazwę. Oznacza to że
jeżeli użyjemy instrukcji przypisania to przypiszemy danej etykiecie
nowy obiekt np.
log=None # obiekt None otrzymuje etykietę log
b=log # obiekt None otrzymuje nowa etykietę b
# teraz jeśli napiszę
log=3 # obiekt 3 otrzymuje etykietę log ale etykieta b nadal odnosi
sie do obiektu None (tak samo )
Pisząc
module1.log= ...
modyfikujesz tylko etykiete w przestrzeni nazw modułu modul1. tylko
importy wykonane po tej instrukcji będą widzieć ta zmianę.
Ale dosyć tych bredni.
Jeżeli chcesz zamiast module1.log.m() pisać log.m() zrezygnuj z
module2 i napisz w module1
class Log(object):
def __init__(self):
pass
def m(self):
print "ok"
log = None
potem piszesz w dowolmym module
from module1 import log
oczywiście jeśli napiszesz potem "gdzieś" module1.log=... to znów
"gdzieś" odnosić się bedziesz do innego obiektu.
i możesz z obiektu log pakować i doczytywać cokolwiek:
log.xxx=3
a winnym module
print log.xxx
Re: Python i importowanie
Author: Michal M
Date: Sun, 20 Dec 2009 22:40
Date: Sun, 20 Dec 2009 22:40
120 lines
5304 bytes
5304 bytes
On 20 Gru, 23:02, marmarprog <marmarp...@gmail.com> wrote: > On 20 Gru, 22:10, Michal M <mmier...@tycowaterworks.pl> wrote: > > > > > > > Ok, ten sam problem się powtórzył. Tym razem podam dokładnie przykład. > > > module1.py > > log = None > > > module2.py > > class Log(object): > > def __init__(self): > > pass > > def m(self): > > print "ok" > > > module3.py > > import module1 > > import module2 > > import module4 > > > module1.log = module2.Log() > > t = module4.Test() > > t.use_m() > > > module4.py > > from module1 import log > > > class Test(object): > > def __init__(self): > > pass > > def use_m(self): > > log.m() > > > Uruchamiam moduł 3. Ja to widzę tak: > > 1. importuje moduły 1, 2 i 3 (czyli udostępnia ich przestrzeń poprzez > > nazwę modułu w module 3) > > 2. pod zmienną log w module 1 podstawia instancję klasy Log z modułu 2 > > 3. Pod zmienną t podstawia instancję klasy Test z modułu 4 i próbuje > > wykonać jej metodę use_m() > > W tym miejscu otrzymuję błąd: AttributeError: 'NoneType' object has no > > attribute 'm' > > > Teraz powiedzmy, że moduł 4 zmienię tak: > > > module4.py > > import module1 > > > class Test(object): > > def __init__(self): > > pass > > def use_m(self): > > module1.log.m() > > > Czyli wg mnie powinno być to samo, tyle że zamiast bezpośrednio do log > > mam dostęp poprzez module1.log. > > Zastanawiałem się, czy może samo log.m() nie widzi jako zmiennej > > lokalnej i nie potrzeba dodać global log ale też nie pomaga. > > Proszę o wyjaśnienie. > > > Pozdrawiam > > Michał > > Python tak działa. > Zmienne można powiedzieć są etykietowane przez nazwę. Oznacza to że > jeżeli użyjemy instrukcji przypisania to przypiszemy danej etykiecie > nowy obiekt np. > log=None # obiekt None otrzymuje etykietę log > b=log # obiekt None otrzymuje nowa etykietę b > # teraz jeśli napiszę > log=3 # obiekt 3 otrzymuje etykietę log ale etykieta b nadal odnosi > sie do obiektu None (tak samo ) > > Pisząc > module1.log= ... > modyfikujesz tylko etykiete w przestrzeni nazw modułu modul1. tylko > importy wykonane po tej instrukcji będą widzieć ta zmianę. > Ale dosyć tych bredni. > Jeżeli chcesz zamiast module1.log.m() pisać log.m() zrezygnuj z > module2 i napisz w module1 > > class Log(object): > def __init__(self): > pass > def m(self): > print "ok" > log = None > > potem piszesz w dowolmym module > from module1 import log > > oczywiście jeśli napiszesz potem "gdzieś" module1.log=... to znów > "gdzieś" odnosić się bedziesz do innego obiektu. > i możesz z obiektu log pakować i doczytywać cokolwiek: > > log.xxx=3 > > a winnym module > > print log.xxx Dzięki za odpowiedź. To nie brednie to pomaga mi zrozumieć to zachowanie (choć jeszcze tego nie ogarniam). Mnie to po prostu wyglądało, że log jest importowane do przestrzeni module4 i zmiana przypisania do tej zmiennej w module 1 nie jest odzwierciedlana w module4. Inaczej jest jeśli odwołuję się przez module1.log. Wtedy odwołuję się do zmiennej właśnie w tamtej przestrzeni nazw (module1). Nie wiem czy to wyjaśnienie jest zbieżne z tym co ty napisałeś (i prawidłowe) ale tłumaczy to zachowanie i jest tym co chciałem na początku przekazać w pierwszym poście. Ze względu na to, że projekt będzie pewnie trochę większy, zrozumienie tego ma dla mnie duże znaczenie. Dlatego też, nie chciałbym przenosić log do modułu w którym jest Log bo chciałbym takie rzeczy trzymać razem w jednym module aby się później nie pogubić (gdzie ja to umieściłem.) Jeszcze raz dziękuję za wyjaśnienie i pozdrawiam.
Re: Python i importowanie
Author: Łukasz Rekucki
Date: Mon, 21 Dec 2009 01:26
Date: Mon, 21 Dec 2009 01:26
27 lines
2709 bytes
2709 bytes
Używanie terminów zmienna i przestrzeń nazw wydaje mi się myląca. Podstawą jest zrozumienie, że "log" w Pythonie nie jest zmienną, a jedynie nazwą wskazującą na jakiś obiekt. Tak więc sytuacja wygląda tak: 0) zaczynasz wykonywanie module3 1) import module1 1.1) do słownika modułu module1 dodawana jest nazwa "log" wskazująca na obiekt None 2) import module2 2.1) wykonywane jest ciało klasy Log 2.2) do nazwy Log w module2 przypisywana jest nowo utworzona klasa Log 3) import module4 3.1) from module1 import log 3.1.1) moduł "module1" jest już zaimportowany, więc odczytywane jest na jaki obiekt wskazuję nazwa "log" w jego słowniku (jest to None) 3.1.2) w słowniku module4 tworzona jest nowa nazwa i wskazuje ona na None 3.2) Tworzona jest klasa Test (analogicznie do klasy Log) 4) module1.log = module2.Log() # nazwa log w słowniku module1 wskazuję teraz na nowy obiekt klasy Log. Słownik module4 jest niezmieniony. 5) t = module4.Test() 6) t.use_m() 6.1) log nie jest lokalne dla use_m, więc jest globalne. Globalnym kontekstem dla use_m() jest module4. module4.log wskazuję na None -> błąd.
Re: Python i importowanie
Author: Michal M
Date: Mon, 21 Dec 2009 08:39
Date: Mon, 21 Dec 2009 08:39
53 lines
3723 bytes
3723 bytes
On 21 Gru, 02:26, Łukasz Rekucki <lreku...@gmail.com> wrote: > Używanie terminów zmienna i przestrzeń nazw wydaje mi się myląca. > Podstawą jest zrozumienie, że "log" w Pythonie nie jest zmienną, a > jedynie nazwą wskazującą na jakiś obiekt. Tak więc sytuacja wygląda > tak: > > 0) zaczynasz wykonywanie module3 > 1) import module1 > 1.1) do słownika modułu module1 dodawana jest nazwa "log" wskazująca > na obiekt None > 2) import module2 > 2.1) wykonywane jest ciało klasy Log > 2.2) do nazwy Log w module2 przypisywana jest nowo utworzona klasa Log > 3) import module4 > 3.1) from module1 import log > 3.1.1) moduł "module1" jest już zaimportowany, więc odczytywane jest > na jaki obiekt wskazuję nazwa "log" w jego słowniku (jest to None) > 3.1.2) w słowniku module4 tworzona jest nowa nazwa i wskazuje ona na > None > 3.2) Tworzona jest klasa Test (analogicznie do klasy Log) > 4) module1.log = module2.Log() # nazwa log w słowniku module1 > wskazuję teraz na nowy obiekt klasy Log. Słownik module4 jest > niezmieniony. > 5) t = module4.Test() > 6) t.use_m() > 6.1) log nie jest lokalne dla use_m, więc jest globalne. Globalnym > kontekstem dla use_m() jest module4. module4.log wskazuję na None -> > błąd. Czyli from module1 import log Tworzy nową zmienną (etykietkę jak wy to nazywacie) w przestrzeni (słowniku) module4 i podstawia pod nią referencję (akurat None, bo się jeszcze nie wykonało podstawienie instancji Log). Natomiast import module1 module1.log Wskazuje na tą samą zmienną którą zmieniam w module1. Innymi słowy, po from module1 import log mam dwie etykietki log i są one niezależne od siebie. Muszę z tym uważać Rozwiązaniem wygodnym byłoby zapisanie w module 4 import module1 log = module1.log ... gdyby nie to, że w każdej funkcji musiałbym dodać global log tak? Wtedy gra nie warta świeczki. No cóż... każdy język ma swoje udziwnienia. :) Dziękuję wszystkim za wyjaśnienia.
Re: Python i importowanie
Author: Michal M
Date: Mon, 21 Dec 2009 08:44
Date: Mon, 21 Dec 2009 08:44
20 lines
2330 bytes
2330 bytes
Przepraszam, że odpowiadam sobie ale nie mogłem wyedytować
poprzedniego postu.
Jeszcze takie pytanie. Gdybym zrobił tak:
module4.py
class Test(object):
def __init__(self):
from module1 import log
pass
def use_m(self):
log.m()
Czyli zaimportował de facto log po podstawieniu pod niego instancji
Log, to powinno działać? Jeśli umieszczę import w funkcji to
zaimportuje do słownika głównego modułu czy do lokalnego funkcji? Da
się tak w ogóle?
(nie jestem tutaj w stanie sprawdzić)
Re: Python i importowanie
Author: Bart Ogryczak
Date: Mon, 21 Dec 2009 11:05
Date: Mon, 21 Dec 2009 11:05
12 lines
1681 bytes
1681 bytes
On Dec 20, 10:10 pm, Michal M <mmier...@tycowaterworks.pl> wrote:
> Tym razem podam dokładnie przykład.
Ok, to co tak naprawdę robisz:
>>> m1 = {'log': None}
>>> m2 = {'Log': 'klasa Log'}
>>> m4 = {'log': m1['log']}
>>> m1['log'] = m2['Log']
>>> m1, m2, m4
({'log': 'klasa Log'}, {'Log': 'klasa Log'}, {'log': None})
Re: Python i importowanie
Author: Michal M
Date: Mon, 21 Dec 2009 12:54
Date: Mon, 21 Dec 2009 12:54
16 lines
2064 bytes
2064 bytes
On 21 Gru, 12:05, Bart Ogryczak <b.ogryc...@gmail.com> wrote:
> On Dec 20, 10:10 pm, Michal M <mmier...@tycowaterworks.pl> wrote:
>
> > Tym razem podam dokładnie przykład.
>
> Ok, to co tak naprawdę robisz:
>
> >>> m1 = {'log': None}
> >>> m2 = {'Log': 'klasa Log'}
> >>> m4 = {'log': m1['log']}
> >>> m1['log'] = m2['Log']
> >>> m1, m2, m4
>
> ({'log': 'klasa Log'}, {'Log': 'klasa Log'}, {'log': None})
Prosto, zwięźle i jasno. Nic dodać, nic ująć. Dziękuję. :)
Re: Python i importowanie
Author: Michal M
Date: Sun, 10 Jan 2010 14:53
Date: Sun, 10 Jan 2010 14:53
65 lines
2916 bytes
2916 bytes
Siedzę w tym Pythonie już jakiś czas i niestety co chwilę stwierdzam,
że to importowanie jest zdrowo po....
przykład:
p1.m2
----------
import m1
import p2.m3
print m1.A.counter
a = m1.A()
print m1.A.counter
p2.m3.get()
p1.m1
---------
class A(object):
counter = 0
def __init__(self):
A.counter = 1
p2.m3
---------
import p1.m1
def get():
print "w def m3: " + str(p1.m1.A.counter)
Po uruchomieniu m2:
0
1
w def m3: 0
Długo kombinowałem jak sprawić aby w m3 widział obiekt A taki jakim
jest naprawdę. i w końcu wyszło, że trzeba przerobić m2:
p1.m2
---------
import p1.m1
import p2.m3
print p1.m1.A.counter
a = p1.m1.A()
print p1.m1.A.counter
p2.m3.get()
Teraz wynik jak oczekiwano:
0
1
w def m3: 1
Tylko, że przy pisaniu większego programu z setkami modułów
rozrzuconych po różnych paczkach to staje się horrorem. Już teraz ok.
80% czasu zajmuje mi kombinowanie z importowaniem aby wszędzie było
widziane to co ma być. Już nie mówię o zmorze cyklicznych odwołań
pomiędzy modułami.
Jest na to jakiś sposób, żeby to opanować?
Jakieś rady?
Tak, próbowałem i ciągle próbuję to zrozumieć ale co chwila się łapie
na tym, że już mi się wydawało, że wszystko ok i znowu coś nie działa.
Re: Python i importowanie
Author: Łukasz Rekucki
Date: Sun, 10 Jan 2010 16:06
Date: Sun, 10 Jan 2010 16:06
69 lines
3493 bytes
3493 bytes
On Jan 10, 3:53 pm, Michal M <mmier...@tycowaterworks.pl> wrote: > Siedzę w tym Pythonie już jakiś czas i niestety co chwilę stwierdzam, > że to importowanie jest zdrowo po.... > > przykład: > > p1.m2 > ---------- > import m1 > import p2.m3 > > print m1.A.counter > a = m1.A() > print m1.A.counter > p2.m3.get() > > p1.m1 > --------- > class A(object): > counter = 0 > def __init__(self): > A.counter = 1 > > p2.m3 > --------- > import p1.m1 > > def get(): > print "w def m3: " + str(p1.m1.A.counter) > > Po uruchomieniu m2: > 0 > 1 > w def m3: 0 > > Długo kombinowałem jak sprawić aby w m3 widział obiekt A taki jakim > jest naprawdę. i w końcu wyszło, że trzeba przerobić m2: > > p1.m2 > --------- > > import p1.m1 > import p2.m3 > > print p1.m1.A.counter > a = p1.m1.A() > print p1.m1.A.counter > p2.m3.get() > > Teraz wynik jak oczekiwano: > 0 > 1 > w def m3: 1 > > Tylko, że przy pisaniu większego programu z setkami modułów > rozrzuconych po różnych paczkach to staje się horrorem. Już teraz ok. > 80% czasu zajmuje mi kombinowanie z importowaniem aby wszędzie było > widziane to co ma być. Już nie mówię o zmorze cyklicznych odwołań > pomiędzy modułami. > > Jest na to jakiś sposób, żeby to opanować? > Jakieś rady? > Tak, próbowałem i ciągle próbuję to zrozumieć ale co chwila się łapie > na tym, że już mi się wydawało, że wszystko ok i znowu coś nie działa. Jeśli masz moduł p1.m2 i chcesz zaimportować moduł p1.m1, to powinieneś zawsze pisać "import p1.m1". To, że "import m1" w ogóle działa, to jest efekt uboczny i takie zachowanie jest "Deprecated". W py3k w ogóle nie znalazł by takiego modułu. W 99% przypadków jeśli twój program wymaga cyklicznych odwołań, to jest z nim coś nie tak.
Re: Python i importowanie
Author: Bart Ogryczak
Date: Mon, 11 Jan 2010 12:38
Date: Mon, 11 Jan 2010 12:38
91 lines
3652 bytes
3652 bytes
On Jan 10, 3:53 pm, Michal M <mmier...@tycowaterworks.pl> wrote:
> Siedzę w tym Pythonie już jakiś czas i niestety co chwilę stwierdzam,
> że to importowanie jest zdrowo po....
>
> przykład:
>
> p1.m2
> ----------
> import m1
> import p2.m3
>
> print m1.A.counter
> a = m1.A()
> print m1.A.counter
> p2.m3.get()
>
> p1.m1
> ---------
> class A(object):
> counter = 0
> def __init__(self):
> A.counter = 1
>
> p2.m3
> ---------
> import p1.m1
>
> def get():
> print "w def m3: " + str(p1.m1.A.counter)
>
> Po uruchomieniu m2:
> 0
> 1
> w def m3: 0
>
> Długo kombinowałem jak sprawić aby w m3 widział obiekt A taki jakim
> jest naprawdę. i w końcu wyszło, że trzeba przerobić m2:
>
> p1.m2
> ---------
>
> import p1.m1
> import p2.m3
>
> print p1.m1.A.counter
> a = p1.m1.A()
> print p1.m1.A.counter
> p2.m3.get()
>
> Teraz wynik jak oczekiwano:
> 0
> 1
> w def m3: 1
>
> Tylko, że przy pisaniu większego programu z setkami modułów
> rozrzuconych po różnych paczkach to staje się horrorem. Już teraz ok.
> 80% czasu zajmuje mi kombinowanie z importowaniem aby wszędzie było
> widziane to co ma być. Już nie mówię o zmorze cyklicznych odwołań
> pomiędzy modułami.
>
> Jest na to jakiś sposób, żeby to opanować?
> Jakieś rady?
> Tak, próbowałem i ciągle próbuję to zrozumieć ale co chwila się łapie
> na tym, że już mi się wydawało, że wszystko ok i znowu coś nie działa.
Coś jest totalnie nie tak z architekturą twoich modułów.
Ja bym zrobił na przykład tak:
p2.m3
---------
class A:
"""abstrakcyjna klasa do nadpisania przez inny moduł"
__init__():
raise NotImplementedError
def get():
counter = A()
print "w def m3: " + str(counter)
p1.m2
----------
import m1
import p2.m3
print m1.A.counter
a = m1.A()
print m1.A.counter
p2.m3.A = m1.A
p2.m3.get()
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