Zaimportuj moduł ze ścieżki względnej


759

Jak zaimportować moduł Python, biorąc pod uwagę jego ścieżkę względną?

Na przykład, jeśli dirFoozawiera Foo.pyi dirBar, i dirBarzawiera Bar.py, w jaki sposób mogę zaimportować Bar.pydo Foo.py?

Oto wizualna reprezentacja:

dirFoo\
    Foo.py
    dirBar\
        Bar.py

Foochce dołączyć Bar, ale restrukturyzacja hierarchii folderów nie wchodzi w grę.


2
Może to wygląda na stackoverflow.com/questions/72852 /...?
Joril,

3
Sprawdź moją odpowiedź, jest jak dotąd najbardziej kompletna, inne nie działają w szczególnych przypadkach, na przykład, gdy wywołujesz skrypt z innego katalogu lub z innego skryptu python. Zobacz stackoverflow.com/questions/279237/…
sorin

Miałem podobny problem i znalazłem to i działa !! apt-get install python-profiler
ldcl289

5
Na wypadek, gdyby ktoś chciał to zrobić statycznie i się tu dostał (tak jak ja :) można również skonfigurować zmienną środowiskową PYTHONPATH
okaram

Lepiej jest postępować zgodnie z instrukcjami w Lib / site.py dla każdej sprawy
Avenida Gez

Odpowiedzi:


333

Zakładając, że oba katalogi są prawdziwymi pakietami Pythona (mają w sobie __init__.pyplik), oto bezpieczne rozwiązanie dla włączenia modułów w zależności od położenia skryptu.

Zakładam, że chcesz to zrobić, ponieważ do skryptu musisz dołączyć zestaw modułów. Używam tego w produkcji w kilku produktach i działa w wielu specjalnych scenariuszach, takich jak: skrypty wywoływane z innego katalogu lub uruchamiane za pomocą Python execute zamiast otwierania nowego interpretera.

 import os, sys, inspect
 # realpath() will make your script run, even if you symlink it :)
 cmd_folder = os.path.realpath(os.path.abspath(os.path.split(inspect.getfile( inspect.currentframe() ))[0]))
 if cmd_folder not in sys.path:
     sys.path.insert(0, cmd_folder)

 # Use this if you want to include modules from a subfolder
 cmd_subfolder = os.path.realpath(os.path.abspath(os.path.join(os.path.split(inspect.getfile( inspect.currentframe() ))[0],"subfolder")))
 if cmd_subfolder not in sys.path:
     sys.path.insert(0, cmd_subfolder)

 # Info:
 # cmd_folder = os.path.dirname(os.path.abspath(__file__)) # DO NOT USE __file__ !!!
 # __file__ fails if the script is called in different ways on Windows.
 # __file__ fails if someone does os.chdir() before.
 # sys.argv[0] also fails, because it doesn't not always contains the path.

Jako bonus, takie podejście pozwala zmusić Python do używania twojego modułu zamiast tych zainstalowanych w systemie.

Ostrzeżenie! Naprawdę nie wiem, co się dzieje, gdy bieżący moduł znajduje się w eggpliku. Prawdopodobnie też zawodzi.


5
czy mogę uzyskać wyjaśnienie, jak to działa? Mam podobny problem i KOCHAM wymusić DIR modułu python zamiast wyszukiwania
carl crott

Uruchamiając Win 7 Pro 64x i Python 2.7 otrzymuję kilka błędów. 1) Musiałem dodać inspekcję do listy importów. 2) Pierwsza wartość [0] w krotce to pusty ciąg. Drugi, [1], pokazuje nazwę pliku. Domyślam się, że pierwszą powinna być ścieżka ... Jakieś pomysły?
Adam Lewis

2
Jeśli idziesz do podkatalogu, należy to tak: os.path.realpath(os.path.abspath(os.path.split(inspect.getfile( inspect.currentframe() ))[0]) + "/subfolder")Do NOT dodać podfolder przed abspathjak to powoduje poważne błędy.
Maximilian Hils,

4
@ scr4ve zamiast tego powinieneś użyć os.path.join () i możesz dodać case ( cmd_subfolder) bezpośrednio do mojej odpowiedzi. dzięki!
sorin,

7
dla mnie realpathjuż generuje ścieżki absolutne, więc nie potrzebuję abspath. Również os.path.dirnamemoże być stosowany zamiast Split, makeing indeksowanie [0]nieaktualne. Linia byłaby wtedy:os.path.realpath(os.path.dirname(inspect.getfile(inspect.currentframe())))
ted

328

Upewnij się, że dirBar ma __init__.pyplik - dzięki temu katalog staje się pakietem Pythona.


204
Pamiętaj, że ten plik może być całkowicie pusty.
Harley Holcombe

47
Jeśli katalog nadrzędny dirBar nie jest sys.pathwtedy obecność __init__.pyw dirBarkatalogu nie pomaga.
jfs

7
-1, dodawanie __init.py__będzie działać tylko wtedy, gdy katalog jest już w sys.path, aw moim przypadku tak nie było. Rozwiązanie „sorin” (zaakceptowane) zawsze działa.
Czarek Tomczak

12
„gdy katalog jest już w sys.path”. Choć całkowicie prawdziwe, jak możemy zgadywać, że katalog nie sys.pathzawierał pytania? Być może coś pominięto, o czym nie widzieliśmy?
S.Lott,

4
Jest to NIE oznacza odpowiedź na pytanie: czy plik inicjalizacji istnieje, czy nie powoduje to, że Python zajrzy do podkatalogów. Jak zdobył setki pozytywnych opinii?
łagodzony

261

Możesz także dodać podkatalog do ścieżki Pythona, aby importował się jak zwykły skrypt.

import sys
sys.path.insert(0, <path to dirFoo>)
import Bar

6
Wygląda na to, że twoja odpowiedź nie działa ze ścieżkami względnymi, patrz stackoverflow.com/questions/279237/…
bogdan

24
Działa to ze ścieżkami względnymi - wystarczy zrozumieć, że ścieżka względna będzie zależeć od tego, z którego katalogu uruchomisz, co czyni to kiepskim rozwiązaniem dla czegoś innego niż szybki hack.
nobar 20.12.12

12
Możesz zrobić coś takiegosys.path.append(os.path.dirname(__file__) + "/relative/path/to/module")
Falko,

lubsys.path.append(__name__ if __name__ != '__main__' else __loader__.fullname)
vim

1
Rozważ użycie, sys.path.insert(0, <path to dirFoo>)ponieważ spowoduje załadowanie tego modułu przed modułami o tej samej nazwie przechowywanymi w innym miejscu.
Anton Tarasenko

117
import os
import sys
lib_path = os.path.abspath(os.path.join(__file__, '..', '..', '..', 'lib'))
sys.path.append(lib_path)

import mymodule

2
Podoba mi się, ponieważ masz elastyczność, aby przejść do katalogu.
Charles L.,

21
Powinieneś użyć os.path.join()zamiast łączenia przez '/', co spowoduje uszkodzenie w (lame) oknach.
0xc0de

18
To nie jest wiarygodne. Zależy to od bieżącego katalogu roboczego, a nie od katalogu, w którym znajduje się skrypt.
jamesdlin

Można dodać tylko wtedy, gdy ścieżka nie jest już na ścieżce. lib_path = os.path.abspath ('../ funkcje'), jeśli lib_path nie jest w sys.path: sys.path.append (lib_path)
Brent

w odpowiedzi na @jamesdlin łącząc kilka odpowiedzi: co powiesz na os.path.abspath(os.path.join(__file__,'..','lib'))?
Matthew Davis,

107

Po prostu wykonaj proste czynności, aby zaimportować plik .py z innego folderu.

Załóżmy, że masz katalog taki jak:

lib/abc.py

Następnie po prostu zachowaj pusty plik w folderze lib o nazwie

__init__.py

A potem użyj

from lib.abc import <Your Module name>

Zachowaj __init__.pyplik w każdym folderze hierarchii modułu importu.


79

Jeśli skonstruujesz swój projekt w ten sposób:

src\
  __init__.py
  main.py
  dirFoo\
    __init__.py
    Foo.py
  dirBar\
    __init__.py
    Bar.py

Następnie z Foo.py powinieneś być w stanie:

import dirFoo.Foo

Lub:

from dirFoo.Foo import FooObject

Zgodnie z komentarzem Toma wymaga to, aby srcfolder był dostępny za pośrednictwem site_packageslub ścieżki wyszukiwania. Ponadto, jak wspomina, __init__.pyjest domyślnie importowany podczas pierwszego importu modułu w tym pakiecie / katalogu. Zazwyczaj __init__.pyjest to po prostu pusty plik.


Wspomnij również, że plik init .py jest importowany podczas importowania pierwszego modułu w tym pakiecie. Twój przykład będzie działał tylko wtedy, gdy src znajduje się w pakiecie site_packages (lub w ścieżce wyszukiwania)
Tom Leys,

3
To najprostsze rozwiązanie, którego szukałem. Jeśli plik do zaimportowania z pewnością znajdzie się w jednym z podkatalogów, to rozwiązanie jest klejnotem.
Deepak GM,

Próbowałem tego samego i nie udało mi się. Nie wiem dlaczego. ImportError: Żaden moduł o nazwie customMath
Ming Li

9
Dlaczego ktoś miałby importować Foo z samego Foo.py. Powinien pochodzić z Bar.py.
bhaskarc

from dirFoo import Foopowiedzieć Foo.bla(). Jeśli używasz, import dirFoo.Foopowinieneś użyć dirFoo.Foo.bla()- dość brzydki, nawet bez futerału na wielbłąda.
Cees Timmerman,

45

Najłatwiejszą metodą jest użycie sys.path.append ().

Jednak możesz być także zainteresowany modułem imp . Zapewnia dostęp do wewnętrznych funkcji importu.

# mod_name is the filename without the .py/.pyc extention
py_mod = imp.load_source(mod_name,filename_path) # Loads .py file
py_mod = imp.load_compiled(mod_name,filename_path) # Loads .pyc file 

Można tego użyć do dynamicznego ładowania modułów, gdy nie znasz nazwy modułu.

Użyłem tego w przeszłości, aby utworzyć interfejs typu wtyczki do aplikacji, w którym użytkownik napisałby skrypt z funkcjami specyficznymi dla aplikacji i po prostu upuściłby swój skrypt w określonym katalogu.

Przydatne mogą być również następujące funkcje:

imp.find_module(name[, path])
imp.load_module(name, file, pathname, description)

Zauważ, że w dokumentacji imp.load_source i imp.load_compiled są wymienione jako przestarzałe. zamiast tego zalecane są imp.find_module i imp.load_module.
amicitas

@amicitas, Może Pan podać żadnego odniesienia za to (muszę go i używam Pythona 2.6 Jestem świadomy tego, co 2,7 docs powiedzieć o nich, ale nie mógł znaleźć żadnego odniesienia w zakresie 2.6.)
0xc0de

@ 0xc0de Można znaleźć tę instrukcję w dokumentacji modułu imp zarówno dla Pythona 2.7.3, jak i Pythona 2.6.7 . Wygląda na to, że tych funkcji nie ma nawet w dokumentacji dla Pythona 3.2.
amicitas

1
Aby zaimportować takie pliki źródłowe w Pythonie 3.3, zobacz Importowanie źródłowego pliku źródłowego python. (Python 3.3+) - Przepełnienie stosu . Dzięki, ludzie za wskazówki tutaj.
nealmcb


23

Najłatwiejszym sposobem bez modyfikacji skryptu jest ustawienie zmiennej środowiskowej PYTHONPATH. Ponieważ sys.path jest inicjowany z następujących lokalizacji:

  1. Katalog zawierający skrypt wejściowy (lub bieżący katalog).
  2. PYTHONPATH (lista nazw katalogów, z taką samą składnią jak zmienna powłoki PATH).
  3. Domyślne ustawienie zależne od instalacji.

Po prostu biegnij:

export PYTHONPATH=/absolute/path/to/your/module

Twój sys.path będzie zawierał powyższą ścieżkę, jak pokazano poniżej:

print sys.path

['', '/absolute/path/to/your/module', '/usr/lib/python2.7', '/usr/lib/python2.7/plat-linux2', '/usr/lib/python2.7/lib-tk', '/usr/lib/python2.7/lib-old', '/usr/lib/python2.7/lib-dynload', '/usr/local/lib/python2.7/dist-packages', '/usr/lib/python2.7/dist-packages', '/usr/lib/python2.7/dist-packages/PIL', '/usr/lib/python2.7/dist-packages/gst-0.10', '/usr/lib/python2.7/dist-packages/gtk-2.0', '/usr/lib/pymodules/python2.7', '/usr/lib/python2.7/dist-packages/ubuntu-sso-client', '/usr/lib/python2.7/dist-packages/ubuntuone-client', '/usr/lib/python2.7/dist-packages/ubuntuone-control-panel', '/usr/lib/python2.7/dist-packages/ubuntuone-couch', '/usr/lib/python2.7/dist-packages/ubuntuone-installer', '/usr/lib/python2.7/dist-packages/ubuntuone-storage-protocol']

13

Moim zdaniem najlepszym wyborem jest umieszczenie __ init __.py w folderze i wywołanie pliku za pomocą

from dirBar.Bar import *

Nie zaleca się używania sys.path.append (), ponieważ coś może pójść nie tak, jeśli użyjesz tej samej nazwy pliku, co istniejący pakiet python. Nie testowałem tego, ale to będzie dwuznaczne.


dziwne, że to from dirBar.Bar import *działa, ale nie from dirBar.Bar import Bar. wiesz dlaczego * działa? co jeśli miałbym wiele plików w dirBar / i chciałbym pobrać tylko kilka z nich (używając metody takiej jak ta, którą tutaj opublikowałeś)?
tester

2
@tester: Użyj from dirBar import Bar.
nobar

@test to dlatego, że fromwskazuje źródło, a wszystko po nim importjest, co można pobrać z tego źródła. from dirBar.Bar import Baroznacza „Ze źródła zaimportuj samo źródło”, co nie ma sensu. że *chociaż środki „dać mi wszystko ze źródła”
FuriousFolder

11

Szybki i brudny sposób dla użytkowników systemu Linux

Jeśli po prostu majstrujesz i nie przejmujesz się problemami z wdrożeniem, możesz użyć dowiązania symbolicznego (zakładając, że twój system plików go obsługuje), aby moduł lub pakiet był bezpośrednio widoczny w folderze żądającego modułu.

ln -s (path)/module_name.py

lub

ln -s (path)/package_name

Uwaga: „Moduł” to dowolny plik z rozszerzeniem .py, a „pakiet” to dowolny folder zawierający ten plik __init__.py(który może być pustym plikiem). Z punktu widzenia użytkowania, moduły i pakiety są identyczne - oba ujawniają zawarte w nich „definicje i instrukcje” zgodnie z żądaniem importpolecenia.

Zobacz: http://docs.python.org/2/tutorial/modules.html


10
from .dirBar import Bar

zamiast:

from dirBar import Bar

na wypadek gdyby mógł być zainstalowany inny dirBar i mylić czytnik foo.py.


2
Nie byłem w stanie tego zrobić w systemie Windows. Czy to na Linuksie?
Gabriel

1
Będzie działać ze skryptu importującego Foo. tzn .: import main.py dirFoo.Foo. Jeśli próbujesz uruchomić Foo.py jako skrypt, zakończy się niepowodzeniem. Zobacz stackoverflow.com/questions/72852/…
jgomo3

9

Aby zaimportować Bar.py do Foo.py, najpierw zamienię te foldery w pakiety Pythona w następujący sposób:

dirFoo\
    __init__.py
    Foo.py
    dirBar\
        __init__.py
        Bar.py

Następnie zrobiłbym to tak w Foo.py:

from .dirBar import Bar

Gdybym chciał, aby przestrzeń nazw wyglądała jak Bar. cokolwiek lub

from . import dirBar

Gdybym chciał przestrzeni nazw dirBar.Bar. cokolwiek . Ten drugi przypadek jest przydatny, jeśli masz więcej modułów w pakiecie dirBar.


7

Dodaj plik __init__.py :

dirFoo\
    Foo.py
    dirBar\
        __init__.py
        Bar.py

Następnie dodaj ten kod na początek Foo.py:

import sys
sys.path.append('dirBar')
import Bar

5
Jeśli dirBarjest już pakietem Python (przez istnienie dirBar/__init__.py), nie ma potrzeby dołączania dirBardo niego sys.path, nie? Oświadczenie import Barz Foo.pypowinno wystarczyć.
Santa

5

Względny przykład sys.path:

# /lib/my_module.py
# /src/test.py


if __name__ == '__main__' and __package__ is None:
    sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../lib')))
import my_module

Na podstawie tej odpowiedzi.


5

Cóż, jak wspomniałeś, zwykle chcesz mieć dostęp do folderu z modułami w stosunku do miejsca uruchamiania skryptu głównego, więc po prostu je zaimportuj.

Rozwiązanie:

Mam skrypt D:/Books/MyBooks.pyi niektóre moduły (np. Oldies.py). Muszę zaimportować z podkatalogu D:/Books/includes:

import sys,site
site.addsitedir(sys.path[0] + '\\includes')
print (sys.path)  # Just verify it is there
import oldies

Umieść print('done')w oldies.py, aby sprawdzić, czy wszystko jest w porządku. Ten sposób zawsze działa, ponieważ według definicji sys.pathjęzyka Python zainicjowanej podczas uruchamiania programu, pierwszym elementem tej listy path[0], jest katalog zawierający skrypt użyty do wywołania interpretera języka Python.

Jeśli katalog skryptów nie jest dostępny (np. Jeśli interpreter jest wywoływany interaktywnie lub jeśli skrypt jest odczytywany ze standardowego wejścia), path[0]to pusty ciąg, który kieruje Python najpierw do wyszukiwania modułów w bieżącym katalogu. Zauważ, że katalog skryptów jest wstawiany przed wpisami wstawionymi w wyniku PYTHONPATH.


1
Musiałem użyć jednego ukośnika zamiast dwóch ukośników odwrotnych (tj. site.addsitedir(sys.path[0]+'/includes')) W moim pierwszym prostym programie Pythona break_time.py: https://github.com/ltfschoen/PythonTest . Używam systemu: MacOS v10.11.5, Python 2.7.12, IDLE IDE 2.7.12, Tk 8.5.9
Luke Schoen

4

Po prostu możesz użyć: from Desktop.filename import something

Przykład:

biorąc pod uwagę, że plik ma nazwę test.pyw katalogu Users/user/Desktopi zaimportuje wszystko.

kod:

from Desktop.test import *

Ale upewnij się, że utworzyłeś pusty plik o nazwie „ __init__.py” w tym katalogu


1
odradzane jest importowanie z gwiazdką. patrz: stackoverflow.com/questions/2386714/why-is-import-bad
axolotl

wiem, dlatego po raz pierwszy napisałem, import somethinga potem powiedziałem, aby ułatwić * zasadniczo nie jest to dobre dla
pamięci

3

Innym rozwiązaniem byłoby zainstalowanie pakietu Py-Require , a następnie skorzystanie z następujących poleceńFoo.py

import require
Bar = require('./dirBar/Bar')

Wygląda na to , że URL to pypi.org/project/require.py i należy pamiętać, że należy go zainstalować za pomocą Pip.
Flash Sheridan,

1
@FlashSheridan Nie, to inny projekt. Usunąłem py-wymagany, ponieważ byłem pewien, że nikt go nie używa, jednak nie pomyślałem o tym poście. Jeśli nadal potrzebujesz require()funkcji, możesz rzucić okiem na mój projekt Node.py
Niklas R

2

Oto sposób na zaimportowanie pliku z jednego poziomu powyżej przy użyciu ścieżki względnej.

Zasadniczo wystarczy przenieść katalog roboczy na wyższy poziom (lub dowolną lokalizację względną), dodać go do ścieżki, a następnie przenieść katalog roboczy z powrotem do miejsca, w którym się zaczął.

#to import from one level above:
cwd = os.getcwd()
os.chdir("..")
below_path =  os.getcwd()
sys.path.append(below_path)
os.chdir(cwd)

1
nie rozumiem twojej logiki tutaj. to jest zbyt skomplikowane
transilvlad

0

Nie mam doświadczenia w pythonie, więc jeśli w moich słowach jest coś złego, po prostu powiedz mi. Jeśli hierarchia plików ułożona jest w następujący sposób:

project\
    module_1.py 
    module_2.py

module_1.pydefiniuje funkcję o nazwie func_1(), module_2.py :

from module_1 import func_1

def func_2():
    func_1()

if __name__ == '__main__':
    func_2()

i uruchomisz python module_2.pyw cmd, wykona to, co func_1()definiuje. Tak zazwyczaj importujemy te same pliki hierarchii. Ale kiedy piszesz from .module_1 import func_1w module_2.py, interpreter Pythona powie No module named '__main__.module_1'; '__main__' is not a package. Aby to naprawić, po prostu zachowujemy zmiany, które właśnie wprowadzamy, i przenosimy oba moduły do ​​pakietu, i uruchamiamy trzeci moduł jako program wywołujący module_2.py.

project\
    package_1\
        module_1.py
        module_2.py
    main.py

main.py :

from package_1.module_2 import func_2

def func_3():
    func_2()

if __name__ == '__main__':
    func_3()

Ale powodem dodamy .zanim module_1w module_2.pyto, że jeśli nie zrobimy tego i run main.py, interpreter Pythona powie No module named 'module_1', że to trochę skomplikowane, module_1.pyjest tuż obok module_2.py. Teraz niech func_1()się module_1.pycoś zrobić:

def func_1():
    print(__name__)

który __name__rejestruje, kto dzwoni do func_1. Teraz trzymamy .przed module_1, uruchom main.py, wydrukuje package_1.module_1, a nie module_1. Wskazuje, że ten, kto dzwoni, func_1()jest w tej samej hierarchii main.py, co .implikuje, że module_1jest w tej samej hierarchii co on module_2.pysam. Więc jeśli nie ma kropki, main.pyrozpozna module_1w tej samej hierarchii co ona, może rozpoznać package_1, ale nie to, co „pod” nią.

Teraz zróbmy to trochę skomplikowanym. Masz a config.inii moduł definiuje funkcję do odczytu w tej samej hierarchii co 'main.py'.

project\
    package_1\
        module_1.py
        module_2.py
    config.py
    config.ini
    main.py

I z jakiegoś nieuniknionego powodu musisz do niego zadzwonić module_2.py, więc musi zostać zaimportowany z wyższej hierarchii. moduł_2.py :

 import ..config
 pass

Dwie kropki oznaczają import z górnej hierarchii (trzy kropki mają dostęp do górnej niż górnej itd.). Teraz możemy uruchomić main.pyinterpreter powie: ValueError:attempted relative import beyond top-level package. „Pakiet najwyższego poziomu” tutaj main.py. Tylko dlatego , że config.pyjest obok main.py, są oni w tej samej hierarchii, config.pynie jest „pod” main.pylub nie jest „prowadzony” przez main.py, więc jest poza main.py. Aby to naprawić, najprostszym sposobem jest:

project\
    package_1\
        module_1.py
        module_2.py
    config.py
    config.ini
main.py

Myślę, że jest to zbieżne z zasadą hierarchii plików projektu, powinieneś rozmieścić moduły z różnymi funkcjami w różnych folderach i po prostu zostawić górnego rozmówcę na zewnątrz, i możesz importować, jak tylko chcesz.


-5

Działa to również i jest znacznie prostsze niż cokolwiek z sysmodułem:

with open("C:/yourpath/foobar.py") as f:
    eval(f.read())

1
Jeśli OP zamierzał zakodować ścieżkę na stałe, mogliby po prostu wstawić tę ścieżkę do PYTHONPATH. Myślę, że chodzi o to, aby nie zakodować ścieżki na stałe, ponieważ niszczyłaby się gdzie indziej.
Matthew

-15

Zadzwoń do mnie zbyt ostrożnie, ale lubię, aby moje były bardziej przenośne, ponieważ nie jest bezpiecznie zakładać, że pliki zawsze będą w tym samym miejscu na każdym komputerze. Osobiście mam kod najpierw wyszukaj ścieżkę do pliku. Używam Linuksa, więc mój wyglądałby tak:

import os, sys
from subprocess import Popen, PIPE
try:
    path = Popen("find / -name 'file' -type f", shell=True, stdout=PIPE).stdout.read().splitlines()[0]
    if not sys.path.__contains__(path):
        sys.path.append(path)
except IndexError:
    raise RuntimeError("You must have FILE to run this program!")

Oczywiście, o ile nie planujesz spakować ich razem. Ale w takim przypadku tak naprawdę nie potrzebujesz dwóch osobnych plików.


11
Super nieefektywny!
0xc0de

1
Pliki zawsze będą znajdować się w tym samym miejscu na każdym komputerze, podając względną ścieżkę.
Sagar Hatekar
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.