Zgodnie C++, jest dobrze znany problem zwany globalny/statyczne zmienne inicjalizacji kolejność f iasco, ze względu na niemożność C++ 's do decydowania o zmiennej globalny/statyczne byłby pierwszy zainicjowany we wszystkich jednostkach kompilacji,
myślę, że sprawozdanie podkreśla kluczową różnicę między Python i C++: w Pythonie, nie ma czegoś takiego jak inna jednostki kompilacyjne. Mam na myśli to, że w C++ (jak wiadomo) dwa różne pliki źródłowe mogą być kompilowane całkowicie niezależnie od siebie, a zatem jeśli porównasz wiersz w pliku A i wiersz w pliku B, nie ma nic do powiedzenia ty, który zostanie umieszczony jako pierwszy w programie. To trochę tak, jak w przypadku wielu wątków: nie można powiedzieć, czy konkretna instrukcja w wątku 1 zostanie wykonana przed czy po określonej instrukcji w wątku 2. Można powiedzieć, że programy w języku C++ są kompilowane równolegle.
W przeciwieństwie do tego w języku Python wykonywanie rozpoczyna się od początku jednego pliku i przebiega w ściśle określonej kolejności przez każdą instrukcję w pliku, rozgałęziając się do innych plików w punktach, w których są importowane.Tak naprawdę można by pomyśleć o dyrektywie import
jako #include
iw ten sposób można zidentyfikować kolejność wykonywania wszystkich linii kodu we wszystkich plikach źródłowych w programie. (Cóż, jest to trochę bardziej skomplikowane, ponieważ moduł jest naprawdę uruchamiany dopiero przy pierwszym importowaniu iz innych powodów.) Jeśli programy w C++ są kompilowane równolegle, programy Python są interpretowane szeregowo.
Twoje pytanie dotyczy także głębszego znaczenia modułów w Pythonie. Moduł Pythona - czyli wszystko, co znajduje się w jednym pliku .py
- jest rzeczywistym obiektem. Wszystko zadeklarowane w "globalnym" zasięgu w jednym pliku źródłowym jest w rzeczywistości atrybutem tego obiektu modułu. W Pythonie nie ma prawdziwego globalnego zasięgu. (Programiści Python często mówią "globalny" i faktycznie jest w tym języku słowo kluczowe global
, ale zawsze odnosi się ono do najwyższego poziomu bieżącego modułu). Widziałem, że jest to trochę dziwna koncepcja, żeby się przyzwyczaić pochodzący z tła C++. Zajęło mi to trochę przyzwyczajenie się do mnie, pochodząc z Javy, a pod tym względem Java jest dużo bardziej podobna do Pythona niż C++. (Nie ma też globalnego zasięgu w Javie)
Wspomnę, że w Pythonie zupełnie normalne jest używanie zmiennej bez żadnego pojęcia, czy została ona zainicjowana/zdefiniowana czy nie. Cóż, może nie normalne, ale przynajmniej dopuszczalne w odpowiednich okolicznościach. W języku Python próba użycia niezdefiniowanej zmiennej powoduje zwiększenie wartości o NameError
; nie zachowujesz się arbitralnie, jak w C lub C++, dzięki czemu łatwo poradzisz sobie z sytuacją. Można zobaczyć ten wzór:
try:
duck.quack()
except NameError:
pass
który nic nie robi, jeśli duck
nie istnieje. Właściwie, co można zobaczyć częściej jest
try:
duck.quack()
except AttributeError:
pass
który nie robi nic, jeśli duck
nie posiada metodę o nazwie quack
. (AttributeError
jest rodzajem błędu, który pojawia się przy próbie uzyskania dostępu do atrybutu obiektu, ale obiekt nie ma żadnego atrybutu o tej nazwie.) To jest to, co przechodzi dla sprawdzenia typu w Pythonie: uważamy, że jeśli wszystko do zrobienia wystarczy kaczka, możemy po prostu poprosić ją o szarlatan, a jeśli tak, to nie obchodzi nas, czy to kaczka, czy nie. (Nazywa się to kaczym pisaniem ;-)
To zdecydowanie dokładne wyjaśnienie problemu, który napisałem, dokładnie do rzeczy! Dzięki! – Lin