__all__ = ["Error", "encode", "decode"]      # Eksportuje tylko te zmienne

from __future__ import nazwa_opcji



### Plik: runme.py

def tester():
   print("Jest Gwiazdka w niebie...")

if __name__ == '__main__':                   # Tylko przy wykonywaniu
   tester()                                  # A nie przy importowaniu




% python
>>> import runme
>>> runme.tester()
Jest Gwiazdka w niebie...  




% python runme.py
Jest Gwiazdka w niebie...  




### Plik: min.py 

def minmax(test, *args):
   res = args[0]
   for arg in args[1:]:
      if test(arg, res):
         res = arg
   return res

def lessthan(x, y): return x < y
def grtrthan(x, y): return x > y

print(minmax(lessthan, 4, 2, 1, 5, 6, 3))    # Kod testu samosprawdzającego
print(minmax(grtrthan, 4, 2, 1, 5, 6, 3))




### Plik: min.py (modified)

print('Jestem:', __name__)

def minmax(test, *args):
   res = args[0]
   for arg in args[1:]:
      if test(arg, res):
         res = arg
   return res

def lessthan(x, y): return x < y
def grtrthan(x, y): return x > y

if __name__ == '__main__':
   print(minmax(lessthan, 4, 2, 1, 5, 6, 3))    # Kod testu samosprawdzającego
   print(minmax(grtrthan, 4, 2, 1, 5, 6, 3))




% python min.py
Jestem: __main__
1
6



>>> import min
Jestem: min
>>> min.minmax(min.lessthan, 'm', 'i', 'e', 'l', 'o', 'n', 'k', 'a')
'a'




### Plik: formats.py

"""
Różne wyspecjalizowane narzędzia służące do formatowania wyświetlanych łańcuchów znaków.
Przetestuj mnie za pomocą gotowego testu samosprawdzającego lub argumentów wiersza poleceń.
"""

def commas(N):
   """
   Formatowanie N podobnego do liczby dodatniej w celu wyświetlenia z przecinkami pomiędzy grupami cyfr, jak w xxx,yyy,zzz.
   """
   digits = str(N)
   assert(digits.isdigit())
   result = ''
   while digits:
      digits, last3 = digits[:-3], digits[-3:]
      result = (last3 + ',' + result) if result else last3
   return result

def money(N, width=0):
   """
   Formatowanie liczby N w celu wyświetlenia jej jako kwoty w dolarach, z przecinkami, dwoma miejscami dziesiętnymi, początkowym symbolem waluty $ i znakiem, a także opcjonalnym dopełnieniem, jak w $ -xxx,yyy.zz.
   """
   sign = '-' if N < 0 else ''
   N = abs(N)
   whole = commas(int(N))
   fract = ('%.2f' % N)[-2:]
   format = '%s%s.%s' % (sign, whole, fract)
   return '$%*s' % (width, format)

if __name__ == '__main__':
   def selftest():
      tests = 0, 1                      # Nie działają: −1, 1.23
      tests += 12, 123, 1234, 12345, 123456, 1234567
      tests += 2 ** 32, 2 ** 100
      for test in tests:
         print(commas(test))
   
      print('')
      tests = 0, 1, −1, 1.23, 1., 1.2, 3.14159
      tests += 12.34, 12.344, 12.345, 12.346
      tests += 2 ** 32, (2 ** 32 + .2345)
      tests += 1.2345, 1.2, 0.2345
      tests += −1.2345, −1.2, −0.2345
      tests += −(2 ** 32), −(2**32 + .2345)
      tests += (2 ** 100), −(2 ** 100)
      for test in tests:
         print('%s [%s]' % (money(test, 17), test))

   import sys
   if len(sys.argv) == 1:
      selftest()
   else:
      print(money(float(sys.argv[1]), int(sys.argv[2])))




C:\misc> python formats.py 999999999 0
$999,999,999.00

C:\misc> python formats.py −999999999 0
$-999,999,999.00

C:\misc> python formats.py 123456789012345 0
$123,456,789,012,345.00

C:\misc> python formats.py −123456789012345 25
$ −123,456,789,012,345.00

C:\misc> python formats.py 123.456 0
$123.46

C:\misc> python formats.py −123.454 0
$-123.45

C:\misc> python formats.py
...gotowe testy — do wypróbowania samodzielnie...




>>> from formats import money, commas
>>> money(123.456)
'$123.46'
>>> money(-9999999.99, 15)
'$ −9,999,999.99'
>>> X = 99999999999999999999
>>> '%s (%s)' % (commas(X), X)
'99,999,999,999,999,999,999 (99999999999999999999)'




>>> import formats
>>> help(formats)
Help on module formats:

NAME
   formats

FILE
   c:\misc\formats.py

DESCRIPTION
   Różne wyspecjalizowane narzędzia służące do formatowania wyświetlanych łańcuchów znaków.
   Przetestuj mnie za pomocą gotowego testu samosprawdzającego lub argumentów wiersza poleceń.

FUNCTIONS
   commas(N)
      Formatowanie N podobnego do liczby dodatniej w celu wyświetlenia z przecinkami pomiędzy grupami cyfr, jak w xxx,yyy,zzz.   

   money(N, width=0)
      Formatowanie liczby N w celu wyświetlenia jej jako kwoty w dolarach, z przecinkami, dwoma miejscami dziesiętnymi, początkowym symbolem waluty $ i znakiem, a także opcjonalnym dopełnieniem, jak w $ -xxx,yyy.zz.




>>> import sys
>>> sys.path
['', 'C:\\users', 'C:\\Windows\\system32\\python30.zip', ...pozostałe usunięto...]

>>> sys.path.append('C:\\sourcedir')         # Rozszerzenie ścieżki wyszukiwania modułów
>>> import string                            # Wszystkie importy przeszukują nowy katalog na końcu




>>> sys.path = [r'd:\temp']                  # Zmiana ścieżki wyszukiwania modułów
>>> sys.path.append('c:\\lp4e\\examples')    # Tylko dla tego procesu
>>> sys.path
['d:\\temp', 'c:\\lp4e\\examples']

>>> import string
Traceback (most recent call last):
   File "<stdin>", line 1, in <module>
ImportError: No module named string




import nazwamodułu as nazwa

import nazwamodułu
nazwa = nazwamodułu
del nazwamodułu                              # Nie zachowujemy oryginalnej nazwy


from nazwamodułu import nazwaatrybutu as nazwa

import naprawdędługanazwamodułu as nazwa       # Użycie krótszego skrótu
name.func()

from moduł1 import narzędzie as narz1          # "narzędzie" może istnieć tylko raz
from moduł2 import narzędzie as narz2
narz1(); narz2()


import dir1.dir2.mod as mod                    # Pełna ścieżka podana tylko raz
mod.func()




M.name                                       # Kwalifikacja obiektu
M.__dict__['name']                           # Ręczne indeksowanie słownika przestrzeni nazw
sys.modules['M'].name                        # Ręczne indeksowanie tabeli załadowanych modułów
getattr(M, 'name')                           # Wywołanie wbudowanej funkcji pobierającej




### Plik: mydir.py

"""
mydir.py: moduł wymieniający przestrzenie nazw innych modułów
"""

seplen = 60
sepchr = '-'

def listing(module, verbose=True):
   sepline = sepchr * seplen
   if verbose:
      print(sepline)
      print('nazwa:', module.__name__, 'plik:', module.__file__)
      print(sepline)

   count = 0
   for attr in module.__dict__:                # Przeszukanie kluczy przestrzeni nazw
      print('%02d) %s' % (count, attr), end = ' ')
      if attr.startswith('__'):
         print('<zmienna wbudowana>')          # Pominięcie __file__ itd.
      else:
         print(getattr(module, attr))          # To samo co .__dict__[attr]
      count += 1

   if verbose:
      print(sepline)
      print(module.__name__, 'ma %d zmiennych' % count)
      print(sepline)

if __name__ == '__main__':
   import mydir
   listing(mydir)                               # Test samosprawdzający — lista samego siebie




>>> import mydir
>>> help(mydir)

C:\misc> c:\Python30\python mydir.py

>>> import mydir
>>> import tkinter
>>> mydir.listing(tkinter)
------------------------------------------------------------
nazwa: tkinter plik: c:\PYTHON30\lib\tkinter\__init__.py
------------------------------------------------------------
...



>>> import "string"
   File "<stdin>", line 1
      import "string"
                    ^
SyntaxError: invalid syntax




x = "string"
import x



>>> modname = "string"
>>> exec("import " + modname)                # Wykonanie łańcucha kodu
>>> string                                   # Zaimportowany w tej przestrzeni nazw
<module 'string' from 'c:\Python30\lib\string.py'>




>>> modname = "string"
>>> string = __import__(modname)
>>> string
<module 'string' from 'c:\Python30\lib\string.py'>




import B                                      # Nie jest przeładowywany razem z A
import C                                      # Importuje załadowany już moduł

% python
>>> . . .
>>> from imp import reload
>>> reload(A)




### Plik: reloadall.py

"""
reloadall.py: przechodnie przeładowanie zagnieżdżonych modułów
"""

import types
from imp import reload                       # from wymagane w wersji 3.0

def status(module): 
   print('przeładowanie' + module.__name__)

def transitive_reload(module, visited):
   if not module in visited:                 # Przechwycenie cykli i powtarzających się modułów
      status(module)                         # Przeładowanie modułu
      reload(module)                         # Przejście do jego modułów podrzędnych
      visited[module] = None
      for attrobj in module.__dict__.values():  # Dla wszystkich atrybutów
         if type(attrobj) == types.ModuleType:  # Rekurencja, jeśli to moduł
            transitive_reload(attrobj, visited)

def reload_all(*args):
   visited = {}
   for arg in args:
      if type(arg) == types.ModuleType:
         transitive_reload(arg, visited)

if __name__ == '__main__':
   import reloadall                          # Kod samosprawdzający: przeładowuje siebie
   reload_all(reloadall)                     # Powinien to przeładować




C:\misc> c:\Python30\python reloadall.py
przeładowanie reloadall
przeładowanie types



>>> from reloadall import reload_all
>>> import os, tkinter

>>> reload_all(os)
przeładowanie os
przeładowanie copyreg
przeładowanie ntpath
przeładowanie genericpath
przeładowanie stat
przeładowanie sys
przeładowanie errno

>>> reload_all(tkinter)
przeładowanie tkinter
przeładowanie _tkinter
przeładowanie tkinter._fix
przeładowanie sys
przeładowanie ctypes
przeładowanie os
przeładowanie copyreg
przeładowanie ntpath
przeładowanie genericpath
przeładowanie stat
przeładowanie errno
przeładowanie ctypes._endian
przeładowanie tkinter.constants




### Nazwy plików w komentarzach

import b                               # Plik a.py
X = 1

import c                               # Plik b.py
Y = 2

Z = 3                                  # Plik c.py

C:\misc> C:\Python30\python
>>> import a
>>> a.X, a.b.Y, a.b.c.Z
(1, 2, 3)

# Modyfikacja wartości przypisań we wszystkich plikach i zapisanie zmian

>>> from imp import reload
>>> reload(a)                          # Normalne przeładowanie tylko na najwyższym poziomie
<module 'a' from 'a.py'>
>>> a.X, a.b.Y, a.b.c.Z
(111, 2, 3)

>>> from reloadall import reload_all
>>> reload_all(a)
przeładowanie a
przeładowanie b
przeładowanie c
>>> a.X, a.b.Y, a.b.c.Z                # Przeładowanie także wszystkich zagnieżdżonych modułów
(111, 222, 333)




func1()                                      # Błąd: "func1" nie została jeszcze przypisana

def func1():
   print(func2())                            # OK: "func2" zostanie wyszukana później

func1()                                      # Błąd: "func2" nie została jeszcze przypisana

def func2():
   return "Witam"

func1()                                      # OK: "func1" i "func2" zostały już przypisane




# Plik: nested1.py
X = 99
def printer(): print(X)


# Plik nested2.py
from nested1 import X, printer               # Kopiuje zmienne
X = 88                                       # Modyfikuje tylko X lokalne!
printer()                                    # X w nested1 nadal ma wartość 99

% python nested2.py
99



# Plik nested3.py
import nested1                               # Pobranie modułu jako całości
nested1.X = 88                               # OK: modyfikuje X z modułu nested1
nested1.printer()

% python nested3.py
88




>>> from module1 import *                    # Źle: może po cichu nadpisać nasze zmienne
>>> from module2 import *                    # Gorzej: skąd mamy wiedzieć, co dostajemy?
>>> from module3 import *
>>> . . .

>>> func()                                   # Hę???




from module import X                         # X może nie odzwierciedlać przeładowanych modułów!
. . .
from imp import reload
reload(module)                               # Modyfikacja modułu, ale nie zmiennych
X                                            # Nadal odnosi się do starego obiektu



import module                                # Pobranie modułu, nie zmiennych
. . .
from imp import reload
reload(module)                               # Modyfikuje moduł w miejscu
module.X                                     # Bieżące X: odzwierciedla przeładowanie modułu




from module import function
function(1, 2, 3)

from imp import reload
reload(module)

from imp import reload
import module
reload(module)
function(1, 2, 3)

from imp import reload
import module
reload(module)
from module import function                  # Można też się poddać i użyć module.function()
function(1, 2, 3)




# Plik recur1.py
X = 1
import recur2                                # Wykonuje recur2, jeśli obiekt modułu nie istnieje
Y = 2

# Plik recur2.py
from recur1 import X                         # OK: "X" jest już przypisane
from recur1 import Y                         # Błąd: "Y" nie jest przypisane

C:\misc> C:\Python30\python
>>> import recur1
Traceback (most recent call last):
   File "<stdin>", line 1, in <module>
   File "recur1.py", line 2, in <module>
      import recur2
   File "recur2.py", line 2, in <module>
      from recur1 import Y
ImportError: cannot import name Y 

