Plik źródłowy może zawierać komentarze, polecenia importu, definicje funkcji, definicje klas oraz kod do wykonania. Kolejność tych elementów jest w dużym stopniu dowolna. Pewne typy komentarzy (opisane niżej) muszą byc na początku pliku. Definicje funkcji i klas wykorzystywanych w kodzie muszą poprzedzać kod. Komentarze Import modułów Funkcje Widoczność zmiennych Opakowania funkcji i dekoratory
print("Zażółć gęślą jaźń")
Traceback (most recent call last): File "", line 1, in import t File "...\test.py", line 1 SyntaxError: Non-ASCII character '\xbf' in file C:\test\t.py on line 1, but no encoding declared;
Za?ˇ?Š gŕťl? jač˝
Zażółć gęślą jaźń
import math math.cos(math.radians(45)) => 0.7071067811865476 import math as m m.sin(m.radians(45)) => 0.7071067811865475Funkcje trygonometryczne w Pythonie oczekują argumentu w radianach, dlatego konieczne jest przeliczenie stopni na radiany.
from math import e e => 2.718281828459045 sqrt(3) Traceback (most recent call last): File "Pełny import (wersje a i b) ma oczywistą wadę: więcej pisania. Skoro jest powszechnie stosowany, to musi mieć również zalety.", line 1, in sqrt(3) NameError: name 'sqrt' is not defined from math import e,sqrt sqrt(3) => 1.7320508075688772
from math import sin sin(0) => 0.0 def sin(x): return x*x+23 sin(0) => 23Zasada (przy niepełnym imporcie) jest taka: widoczny (dostępny) jest ten obiekt, który został zaimportowany (zdefiniowany) najpóźniej.
import math help(math) => Help on built-in module math: NAME math FILE (built-in) DESCRIPTION This module is always available. It provides access to the mathematical functions defined by the C standard. FUNCTIONS acos(...) acos(x) Return the arc cosine (measured in radians) of x. ... dir(math) => ['__doc__', '__name__', 'acos ',....., 'tanh']
import test test.math.exp(3) => 20.085536923187668Ani słowa test, ani słowa math nie można opuścić.
Importowany moduł jest kompilowany do kodu bajtowego - powstaje plik z rozszerzeniem pyc. Pliki te są niezależne od od platformy - plik pyc utworzony
na Linuksie będzie działał w systemie Windows i na odwrót.
Zgodnie z dokumentacją, czas wykonywania modułów i programów skompilowanych jest taki sam jak nieskompilowanych. Krótszy jest natomiast czas ładowania do pamięci.
Kompilację możemy wymusić, kompilator znajduje sie w module compileall:
import compileall compileall.compile_dir(nazwaKatalogu)Metoda compile_dir ma kilka parametrów domyślnych.
compileall.compile_dir('test',force=True,maxlevels=1)Kolejność parametrów jest nieistotna, można napisać np. tak:
compileall.compile_dir(maxlevels=1,dir='test',force=True)Tzn. przy wywoływaniu funkcji z wieloma argumentami nie musimy pamiętać w jakiej kolejności wpisać parametry. Wystarczy, że znamy nazwy argumentów.
def f(x,y=11,z=23): return x+y+zArgument y ma wartośc domyślną 11, a argument z ma wartość domyślną 23. Argumenty z wartością domyślną (keyword arguments, argumenty słownikowe) muszą być na końcu listy argumentów.
f(1,2,3) => 6 f(1,2) => 26 f(1) => 35 f(1,z=4) => 16Wywołanie funkcji zawsze wymaga napisania nawiasów, również wtedy gdy funkcja jest bezargumentowa lub wszystkie argumenty maja wartości domyślne. Napisanie nazwy funkcji bez nawiasów nie jest błędem, ale nie jest też wywołaniem funkcji.
def f(tekst="ma",ileRazy=2): 'funkcja zwraca tekst*ileRazy, default: tekst="ma", ileRazy=2' return tekst*ileRazy g() => 'mama' g => <function g at 0x01230970> g.__doc__ => 'funkcja zwraca tekst*ileRazy, default: tekst="ma", ileRazy=2'Pierwszy wiersz definicji funkcji może być typu str. Nie należy on do ciała funkcji, jest on krótką dokumentacją funkcji. Można go odczytać poleceniem nazwaFunkcji.__doc__. Taką dokumentację ma każda standardowa funkcja Pythona.
len => <built-in function len> len.__doc__ => 'len(object) -> integer\n\nReturn the number of items of a sequence or mapping.'
Można definiować funkcje, które przyjmują dowolną (nieznaną w czasie definiowania funkcji) ilość argumentów.
def suma(*a): s = 0 for x in a: s+=x return s suma(2,3,4) => 9 suma(*(2,5,77)) => 84 suma(*range(1399)) => 977901Operator * w ostatnich dwóch przykładach rozpakowuje kolekcję (krotkę, listę) tworząc osobne zmienne.
def sklej(separator,*items): return separator.join(items) sklej("_","o","co","chodzi") => 'o_co_chodzi'
def cheeseshop(kind, *arguments, **keywords): print "-- Do you have any", kind, "?" print "-- I'm sorry, we're all out of", kind for arg in arguments: print arg print "-" * 40 keys = sorted(keywords.keys()) for kw in keys: print kw, ":", keywords[kw]Wywołanie funkcji:
cheeseshop("Limburger", "It's very runny, sir.", "It's really very, VERY runny, sir.", shopkeeper='Michael Palin', client="John Cleese", sketch="Cheese Shop Sketch")Efekt działania funkcji:
-- Do you have any Limburger ? -- I'm sorry, we're all out of Limburger It's very runny, sir. It's really very, VERY runny, sir. --------------------------------------- client : John Cleese shopkeeper : Michel Palin sketch : Cheese Shop Sketch
x = 'globalna' def f(t): x = 'lokalna' print locals() print x print globals()['x'] f(11) => {'x': 'lokalna', 't': 11} lokalna globalna x => 'globalna'W ciele funkcji f zmienna globalna x została przesłonięta zmienną lokalną x. Funkcja globals() umożliwia dostęp do przesłoniętej zmiennej globalnej x.
def f(a): x = 5 def h(b): print a print locals() h(200) f(1) => 1 {'a': 1, 'b': 200}Ani przekazany do funkcji f parametr a, ani jej zmienna lokalna x nie są automatycznie elementami lokalnej przestrzeni nazw funkcji zagnieżdżonej h. W powyższym przykładzie, polecenie print a dopisało parametr a do lokalnej przestrzeni nazw funkcji h.
def f(): globals()['x'] = 1000 # słownik globals() zawiera zmienne zdefiniowane w konsolipo czym wpisujemy polecenia:
x = 1 f() print x => 1000
x = 10 def f(): globals()['x']=1000 # słownik globals() zawiera zmienne zdefiniowane w module a (tzn. w pliku a.py)Wpisujemy w konsoli Pythona polecenia:
x = 1 import a a.f() x => 1
counters={} def licz_wywolania(f): def wrapper(*arguments,**keywords): key = 'counter_'+f.__name__ if counters.has_key(key): counters[key] += 1 else: counters[key] = 1 return f(*arguments,**keywords) return wrapperFunkcja opakowująca licz_wywołania(f) dopisuje przed ciałem funkcji f kod liczący wywołania funkcji f. Drugim krokiem będzie "opakowanie" pewnych funkcji:
len = licz_wywolania(len) str = licz_wywolania(str)Wywołamy parokrotnie "opakowane" funkcje:
len('123') => 3 len(counters) => 1 len(range(33)) => 33 str(34) => '34' str(34.55) => '34.55'i zajrzymy do słownika:
counters => {'counter_len': 3, 'counter_str': 2}Jeżeli chcemy opakować funkcje biblioteczne, to opisany wyżej sposób jest jedyny. Jeżeli mamy dostęp do kodu źródłowego funkcji, to istnieje drugi sposób opakowania - użycie dekoratorów.
def foo(): print 'Jestem Foo' foo = licz_wywolania(foo) for i in range(10): foo() @licz_wywolania def boo(): print 'Jestem Boo' for i in range(10): boo() counters => {'counter_foo': 10, 'counter_len': 3, 'counter_boo': 10, 'counter_str': 2}W Django każdy adres jest mapowany na pewną funkcję. Załóżmy, że adres .../save jest mapowany na funkcję save_page, a dostęp do tego adresu powinni mieć tylko zalogowani użytkownicy. Będziemy w takiej sytuacji korzystać z dekoratora:
@login_required(login_url="/login/") def save_page(request): ...Lub
@login_required def save_page(request): ...Obie wersje dekoratora opakowują funkcję save_page dodając sprawdzenie czy użytkownik jest zalogowany, jeśli nie jest, to jest kierowany na stronę logowania (jej adres podajemy jako parametr login_url w pierwszej wersji dekoratora, lub w pliku settings.py w wierszu postaci LOGIN_URL = '/login/'), a po pomyślnym logowaniu jest kierowany na stronę .../save. Identycznie "dekorujemy" wszystkie strony wymagające zalogowania.
@permission_required('user.is_superuser',login_url="/login/") def save_page(request): ...Dekorator ten opakowuje funkcję save_page dodając sprawdzenie czy użytkownik jest zalogowany i czy spełnia warunek będacy pierwszym argumentem funkcji permission_required, jeśli nie jest, to jest kierowany na stronę logowania, a po pomyślnym logowaniu jest kierowany na stronę .../save.