__Init__.py යනු කුමක්ද?


2353

කුමක්ද __init__.pyඑය Python කේත බහලුම සඳහා?


16
CommentRob_before_edits සහ මෙම stackoverflow thread 37139786 හි පහත දැක්වෙන අදහස් වලට අනුව , පයිතන් 3.3+ සඳහා init .py තවදුරටත් අවශ්‍ය නොවන බව පෙනේ .
Jun711

Answers:


1464

එය පැකේජයක අත්‍යවශ්‍ය කොටසක් විය ( පැරණි, පෙර -3.3 “ සාමාන්‍ය පැකේජය” මිස නව 3.3+ “නාම අවකාශ පැකේජය” නොවේ ).

මෙන්න ලියකියවිලි.

පයිතන් පැකේජ වර්ග දෙකක් අර්ථ දක්වයි, සාමාන්‍ය පැකේජ සහ නාම අවකාශ පැකේජ. නිත්‍ය පැකේජ සාම්ප්‍රදායික පැකේජ වන අතර ඒවා පයිතන් 3.2 සහ ඊට පෙර පැවති ඒවාය. සාමාන්‍ය පැකේජයක් සාමාන්‍යයෙන් __init__.pyගොනුවක් අඩංගු නාමාවලියක් ලෙස ක්‍රියාත්මක වේ . සාමාන්‍ය පැකේජයක් ආනයනය කරන විට, මෙම __init__.pyගොනුව ව්‍යංගයෙන් ක්‍රියාත්මක වන අතර, එය අර්ථ දක්වන වස්තු පැකේජයේ නාම අවකාශයේ නම් වලට බැඳී ඇත. මෙම __init__.pyගොනුව ඕනෑම මොඩියුලය අඩංගු හැකි බව එම පිඹුරා කේතය අඩංගු විය හැක, එය ආනයනය කරන විට පිඹුරා මෙම මොඩියුලය සඳහා සමහර අතිරේක ගුණාංග එකතු වනු ඇත.

නමුත් සබැඳිය ක්ලික් කරන්න, එහි නිදසුනක්, වැඩි විස්තර සහ නාම අවකාශ පැකේජ පිළිබඳ පැහැදිලි කිරීමක්, නැති ආකාරයේ පැකේජ අඩංගු __init__.pyවේ.


188
මෙයින් අදහස් කරන්නේ කුමක්ද: "මෙය සිදු කරනුයේ නූල් වැනි පොදු නමක් ඇති නාමාවලි නොදැනුවත්වම මොඩියුල සෙවුම් මාවතේ සිදුවන වලංගු මොඩියුලයන් නොදැනුවත්ව සැඟවීම වැළැක්වීම සඳහාද?"
කාල් ජී

98
ArCarlG Python විසින් ආනයන ප්‍රකාශනවල නම් නිරාකරණය කිරීම සඳහා නාමාවලි ලැයිස්තුවක් සොයයි . මේවා ඕනෑම නාමාවලියක් විය හැකි අතර, අත්තනෝමතික ඒවා අවසාන පරිශීලකයාට එකතු කළ හැකි බැවින්, ඩොක්ස් උදාහරණයේ ඇති 'string' වැනි වලංගු පයිතන් මොඩියුලයක් සමඟ නමක් බෙදා ගැනීමට සිදුවන නාමාවලි ගැන සංවර්ධකයින්ට කරදර විය යුතුය. මෙය සමනය කිරීම සඳහා, එය _ _ init _ _.py (හිස් අවකාශයක් නැත) නම් ගොනුවක් අඩංගු නොවන නාමාවලි නොසලකා හරිනු ලැබේ.
ද්වි-බිට් ඇල්කෙමිස්ට්

188
ArCarlG මෙය උත්සාහ කරන්න. 'ඩේටයිම්' නමින් නාමාවලියක් සාදන්න, එහි හිස් ලිපිගොනු දෙකක් සාදන්න, එනම් init.py ගොනුව (යටි ඉරි සහිත) සහ datetime.py. දැන් පරිවර්තකයෙකු විවෘත කර, sys ආනයනය කර නිකුත් කරන්න sys.path.insert(0, '/path/to/datetime'), ඔබ විසින් සාදන ලද ඕනෑම නාමාවලියකට එම මාර්ගය ආදේශ කරන්න. දැන් වැනි දෙයක් උත්සාහ කරන්න from datetime import datetime;datetime.now(). ඔබට AttributeError ලබා ගත යුතුය (මන්ද එය දැන් ඔබගේ හිස් ගොනුව ආනයනය කරන බැවිනි). හිස් init ගොනුව නිර්මාණය නොකර ඔබ මෙම පියවර නැවත කරන්නේ නම්, මෙය සිදු නොවේ. එය වැළැක්වීමට අදහස් කරන්නේ එයයි.
ද්වි-බිට් ඇල්කෙමිස්ට්

4
@ DarekNędza ඔබට පයිතන් පරිවර්තකයක් විවෘත කර from datetime import datetimeදෝෂයකින් තොරව නිකුත් කළ නොහැකි නම් ඔබ වැරදි ලෙස යමක් සකසා ඇත . 2.3 අනුවාදය දක්වාම එය හොඳයි!
ද්වි-බිට් ඇල්කෙමිස්ට්

5
WSWang: එය වැරදියි: builtinsසාදන ලද මොඩියුලයන් නොව, සාදන ලද කාර්යයන් සහ පන්ති ලැයිස්තුගත කරයි (cf. docs.python.org/3/tutorial/modules.html#the-dir-function ). ඔබට සාදන ලද මොඩියුල ලැයිස්තුගත කිරීමට අවශ්‍ය නම් , කරන්න import sys; print(sys.builtin_module_names)(cf. docs.python.org/3/library/sys.html#sys.builtin_module_names ).
මැග්ජීරෝ

848

නම් කරන ලද ලිපිගොනු __init__.pyතැටියේ නාමාවලි පයිතන් පැකේජ නාමාවලි ලෙස සලකුණු කිරීමට භාවිතා කරයි. ඔබට ලිපිගොනු තිබේ නම්

mydir/spam/__init__.py
mydir/spam/module.py

හා mydirගමනට, ඔබ තුළ ඇති කේතය ආයාත කළ හැකි වේ module.pyලෙස

import spam.module

හෝ

from spam import module

ඔබ __init__.pyගොනුව ඉවත් කළහොත් , පයිතන් තවදුරටත් එම නාමාවලිය තුළ උප මොඩියුල සොයන්නේ නැත, එබැවින් මොඩියුලය ආනයනය කිරීමට ගන්නා උත්සාහයන් අසාර්ථක වනු ඇත.

මෙම __init__.pyගොනුව හිස් සාමාන්යයෙන්, නමුත් බොහෝ විට ඔබට වඩාත් පහසු නම, අල්ලා පහසුව කාර්යයන් යටතේ පැකේජය තෝරා ගත් කොටස් අපනයනය කිරීම සඳහා init මොඩියුලය අන්තර්ගතය ලෙස භාවිතා කළ හැකි, ඉහත උදාහරණයේ දී ආදිය, භාවිතා කළ හැක

import spam

මත පදනම් වූ මෙම


96
යාවත්කාලීන කිරීම: ගොනුව __init__.pyපයිතන් 2.X යටතේ අවශ්‍ය වූ අතර එය තවමත් පයිතන් 2.7.12 යටතේ අවශ්‍ය වේ (මම එය පරීක්ෂා කළෙමි) නමුත් එය තවදුරටත් (යැයි කියනු ලබන) පයිතන් 3.3 සිට අවශ්‍ය නොවන අතර පයිතන් 3.4.3 (I) යටතේ අවශ්‍ය නොවේ. එය පරීක්ෂා කර ඇත). වැඩි විස්තර සඳහා stackoverflow.com/questions/37139786 බලන්න .
Rob_before_edits

4
එය භාවිතා නොකරන්න. එය "නාම අවකාශ" පැකේජයක් මිස සාමාන්‍ය පැකේජයක් නොවේ. නාම අවකාශ පැකේජය ඉතා දුර්ලභ භාවිත අවස්ථා සඳහා භාවිතා කරයි. එය භාවිතා කරන විට ඔබ දැන ගැනීමට අවශ්‍ය නොවනු ඇත. භාවිතා කරන්න __init__.py.
මීතේන්

2
කෙසේ වෙතත් ඔබ සතුව තිබේ නම් setup.pyසහ ඔබ භාවිතා find_packages()කරන්නේ නම් එය __init__.pyසෑම නාමාවලියකම තිබිය යුතුය. Stackoverflow.com/a/56277323/7127824
techkuz

487

ඩිරෙක්ටරියක් පයිතන් පැකේජයක් ලෙස ලේබල් කිරීමට සහ නිර්වචනය කිරීමට අමතරව __all__, __init__.pyපැකේජ මට්ටමින් ඕනෑම විචල්‍යයක් අර්ථ දැක්වීමට ඔබට ඉඩ සලසයි. ඒපීඅයි වැනි මෝස්තරයකින් නිතර ආනයනය කරනු ලබන යමක් පැකේජයක් අර්ථ දක්වන්නේ නම් එසේ කිරීම බොහෝ විට පහසුය. මෙම රටාව පයිතොනික් "පැතලි කැදැල්ලට වඩා හොඳයි" දර්ශනයට අනුගත වීම ප්රවර්ධනය කරයි.

උදාහරණයක්

මෙන්න මගේ එක් ව්‍යාපෘතියක උදාහරණයක්, මගේ දත්ත සමුදාය සමඟ අන්තර් ක්‍රියා කිරීමට මම නිතරම sessionmakerඇමතුමක් ආනයනය Sessionකරමි. මම මොඩියුල කිහිපයක් සහිත "දත්ත සමුදා" පැකේජයක් ලිවීය:

database/
    __init__.py
    schema.py
    insertions.py
    queries.py

මගේ __init__.pyපහත කේතය අඩංගු වේ:

import os

from sqlalchemy.orm import sessionmaker
from sqlalchemy import create_engine

engine = create_engine(os.environ['DATABASE_URL'])
Session = sessionmaker(bind=engine)

මම Sessionමෙහි අර්ථ දක්වන බැවින් , පහත සින්ටැක්ස් භාවිතයෙන් මට නව සැසියක් ආරම්භ කළ හැකිය. මෙම කේතය "දත්ත සමුදා" පැකේජ නාමාවලිය තුළ හෝ පිටත සිට ක්‍රියාත්මක වේ.

from database import Session
session = Session()

ඇත්ත වශයෙන්ම, මෙය කුඩා පහසුවකි - විකල්පය වනුයේ Sessionමගේ දත්ත සමුදා පැකේජයේ "create_session.py" වැනි නව ගොනුවක අර්ථ දැක්වීම සහ මෙය භාවිතා කරමින් නව සැසි ආරම්භ කිරීමයි:

from database.create_session import Session
session = Session()

තවදුරටත් කියවීම

සුදුසු භාවිතයන් ආවරණය වන පරිදි ලස්සන රසවත් රතු නූල් ඇත __init__.py ඇත:

http://www.reddit.com/r/Python/comments/1bbbwk/whats_your_opinion_on_what_to_include_in_init_py/

බහුතර මතය නම් __init__.py, “පැහැදිළිව ගම්‍ය වන දර්ශනයට වඩා හොඳය” දර්ශනය උල්ලං ting නය නොකිරීමට ලිපිගොනු ඉතා තුනී විය යුතු බවයි.


3
engine, sessionmaker, create_engine, සහ osද සියලු ආනයනය කළ හැකි databaseදැන් ... ඔබ නාම පිළිබඳ අවුල් කර තියෙනවා වගේ මට මතකයි.
ArtOfWarfare

9
RArtOfWarfare, ඔබට __all__ = [...]ආනයනය කරන දේ සීමා කිරීමට භාවිතා කළ හැකිය import *. නමුත් එය පසෙක තබා, ඔව්, ඔබට ඉතිරිව ඇත්තේ අවුල් සහගත ඉහළ මට්ටමේ නාම අවකාශයකි.
නේතන් ගුල්ඩ්

'දත්ත සමුදාය URL' යනු කුමක්දැයි මට දැනගත හැකිද? Create_engine 'mysql + mysqldb: // root: python @ localhost: 3306 / test' සමඟ සම්බන්ධ කිරීමෙන් මම මෙය ප්‍රතිවර්තනය කිරීමට උත්සාහ කළ නමුත් එය ක්‍රියාත්මක නොවේ. ස්තූතියි.
සනීබොයිස්

2
පැකේජයේ ඇතුළත සිට init හි අර්ථ දක්වා ඇති 'සැසිය' පන්තියට ඔබ පිවිසෙන්නේ කෙසේද ? උදා: quieries.py?
vldbnc

258

ඊට ප්‍රධාන හේතු 2 ක් ඇත __init__.py

  1. පහසුව සඳහා: ඔබේ පැකේජ ධූරාවලිය තුළ ඔබගේ කාර්යයන් නිශ්චිත ස්ථානය අනෙක් පරිශීලකයින්ට දැන ගැනීමට අවශ්‍ය නොවනු ඇත.

    your_package/
      __init__.py
      file1.py
      file2.py
        ...
      fileN.py
    # in __init__.py
    from file1 import *
    from file2 import *
    ...
    from fileN import *
    # in file1.py
    def add():
        pass

    එවිට අනෙක් අයට by () මගින් ඇමතිය හැකිය

    from your_package import add

    file1 නොදැන, වැනි

    from your_package.file1 import add
  2. ඔබට යමක් ආරම්භ කිරීමට අවශ්‍ය නම්; උදාහරණයක් ලෙස, ලොග් වීම (ඒවා ඉහළ මට්ටමට දැමිය යුතුය):

    import logging.config
    logging.config.dictConfig(Your_logging_config)

7
ඔහ්, ඔබේ පිළිතුර කියවීමට පෙර, මම සිතුවේ ශ්‍රිතයක් එහි ස්ථානයෙන් පැහැදිලිව කැඳවීම හොඳ පුරුද්දක් බවයි.
Aerin

2
කෙටි ප්‍රකාශ (හෝ, මේ අවස්ථාවේ දී, ආත්මීය නිගමන) සැමවිටම සත්‍ය යැයි නොසැලකීම වඩා හොඳය. සිට ආනයනය කිරීම __init__.pyසමහර විට ප්‍රයෝජනවත් විය හැකි නමුත් සෑම විටම නොවේ.
ටොබියාස් සෙට්

111

මෙම __init__.pyගොනුව මොඩියුල ලෙස අඩංගු Python සංග්රහ බහලුම් කරයි.

තවද, මොඩියුලයක පැටවූ පළමු ගොනුව මෙයයි, එබැවින් ඔබට මොඩියුලයක් පටවන සෑම අවස්ථාවකම ක්‍රියාත්මක කිරීමට අවශ්‍ය කේතය ක්‍රියාත්මක කිරීමට හෝ අපනයනය කළ යුතු උප මොඩියුල නියම කිරීමට ඔබට එය භාවිතා කළ හැකිය.


89

පයිතන් 3.3 සිට, __init__.pyආනයනය කළ හැකි පයිතන් පැකේජ ලෙස නාමාවලි අර්ථ දැක්වීම තවදුරටත් අවශ්‍ය නොවේ.

PEP 420 පරීක්ෂා කරන්න : ව්‍යාජ නාම අවකාශ පැකේජ :

__init__.pyසලකුණු ලිපිගොනු අවශ්‍ය නොවන සහ ස්වයංක්‍රීයව බහුවිධ කොටස් බෙදිය හැකි පැකේජ නාමාවලි සඳහා ස්වදේශීය සහාය ( PEP 420 හි විස්තර කර ඇති පරිදි, නාම අවකාශ පැකේජ සඳහා විවිධ තෙවන පාර්ශවීය ප්‍රවේශයන්ගෙන් දේවානුභාවයෙන් )

මෙන්න පරීක්ෂණය:

$ mkdir -p /tmp/test_init
$ touch /tmp/test_init/module.py /tmp/test_init/__init__.py
$ tree -at /tmp/test_init
/tmp/test_init
├── module.py
└── __init__.py
$ python3

>>> import sys
>>> sys.path.insert(0, '/tmp')
>>> from test_init import module
>>> import test_init.module

$ rm -f /tmp/test_init/__init__.py
$ tree -at /tmp/test_init
/tmp/test_init
└── module.py
$ python3

>>> import sys
>>> sys.path.insert(0, '/tmp')
>>> from test_init import module
>>> import test_init.module

යොමුව:
https://docs.python.org/3/whatsnew/3.3.html#pep-420-implicit-namespace-packages
https://www.python.org/dev/peps/pep-0420/
යනු __init__. python 3 හි පැකේජ සඳහා py අවශ්‍ය නොවේද?


3
එය "නාම අවකාශය" පැකේජයයි. සාමාන්‍ය පැකේජයක් සඳහා එය භාවිතා නොකරන්න.
මීතේන්

@ මෙතන්, ඔබේ අදහස විස්තාරණය කළ හැකිද?
රොබට් ලග්

3
O රොබට්ලග් බලන්න dev.to/methane/don-t-omit-init-py-3hga
මීතේන්

57

පයිතන්හි පැකේජයේ අර්ථ දැක්වීම ඉතා සරල ය. ජාවා මෙන් ධූරාවලි ව්‍යුහය සහ නාමාවලි ව්‍යුහය සමාන වේ. නමුත් ඔබට __init__.pyපැකේජයක් තිබිය යුතුය. __init__.pyපහත උදාහරණය සමඟ මම ගොනුව පැහැදිලි කරමි :

package_x/
|--  __init__.py
|--    subPackage_a/
|------  __init__.py
|------  module_m1.py
|--    subPackage_b/
|------  __init__.py
|------  module_n1.py
|------  module_n2.py
|------  module_n3.py

__init__.pyඑය පවතින තාක් කල් හිස් විය හැකිය. නාමාවලිය පැකේජයක් ලෙස සැලකිය යුතු බව එයින් ඇඟවෙයි. ඇත්ත වශයෙන්,__init__.py සුදුසු අන්තර්ගතයන් සැකසිය හැකිය.

අපි මොඩියුලය_එන් 1 හි ශ්‍රිතයක් එකතු කළහොත්:

def function_X():
    print "function_X in module_n1"
    return

ධාවනය කිරීමෙන් පසු:

>>>from package_x.subPackage_b.module_n1 import function_X
>>>function_X()

function_X in module_n1 

ඉන්පසු අපි ධූරාවලිය පැකේජය අනුගමනය කර මොඩියුලය_එන් 1 ශ්‍රිතය ලෙස හැඳින්වුවෙමු. අපට මේ ආකාරයට __init__.pysubPackage_b හි භාවිතා කළ හැකිය :

__all__ = ['module_n2', 'module_n3']

ධාවනය කිරීමෙන් පසු:

>>>from package_x.subPackage_b import * 
>>>module_n1.function_X()

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

එබැවින් * ආයාත කිරීම, මොඩියුල පැකේජය __init__.pyඅන්තර්ගතයට යටත් වේ.


ඇසුරුම් කරන ලද පුස්තකාලය හරහා එකම ආනයනය කිරීමට මගේ setup.py පෙනෙන්නේ කෙසේද? from package_x.subPackage_b.module_n1 import function_X
technazi

එබැවින් මෙහි ඇති යතුර වන්නේ "ආනයනය කිරීම * භාවිතා කිරීම, මොඩියුලය පැකේජය init .py අන්තර්ගතයට යටත් වේ"
මිනි

55

__init__.pyගොනුවක් නොමැතිව පයිතන් ක්‍රියා කළද ඔබ තවමත් එකක් ඇතුළත් කළ යුතුය.

පැකේජයක් මොඩියුලයක් ලෙස සැලකිය යුතු බව එය නියම කරයි, එබැවින් එය ඇතුළත් කරන්න (එය හිස් වුවද).

ඔබට ඇත්ත වශයෙන්ම __init__.pyගොනුවක් භාවිතා කළ හැකි අවස්ථාවක් ද ඇත :

ඔබට පහත ගොනු ව්‍යුහයක් ඇතැයි සිතන්න:

main_methods 
    |- methods.py

හා methods.pyඅන්තර්ගත:

def foo():
    return 'foo'

භාවිතා කිරීමට foo()ඔබට පහත සඳහන් දේවලින් එකක් අවශ්‍ය වේ:

from main_methods.methods import foo # Call with foo()
from main_methods import methods # Call with methods.foo()
import main_methods.methods # Call with main_methods.methods.foo()

සමහර විට ඔබට methods.pyඇතුළත තබා ගැනීමට අවශ්‍ය (හෝ අවශ්‍ය) main_methods(උදාහරණයක් ලෙස ධාවන කාල / පරායත්තතා) නමුත් ඔබට අවශ්‍ය වන්නේ ආනයනය කිරීමට පමණි main_methods.


ඔබ නම වෙනස් නම් methods.pyකිරීමට __init__.pyනම් ඔබ භාවිතා කළ හැකි foo()යන්තම් ආනයනය විසින් main_methods:

import main_methods
print(main_methods.foo()) # Prints 'foo'

මෙය ක්‍රියාත්මක __init__.pyවන්නේ පැකේජයේ කොටසක් ලෙස සලකන බැවිනි .


සමහර පයිතන් පැකේජ ඇත්ත වශයෙන්ම මෙය කරයි. උදාහරණයක් සමඟ JSON ධාවනය කොහේද, import jsonඇත්තටම ආනයනය කරනු __init__.pyසිට jsonපැකේජය ( මෙහි පැකේජය ගොනු ව්යුහය බලන්න ):

ප්රභව කේතය: Lib/json/__init__.py


39

__init__.py එය ඇති බහලුම පැටවිය හැකි මොඩියුලයක් ලෙස සලකනු ඇත.

කේත කියවීමට කැමති අය සඳහා, මම ද්වි-බිට් ඇල්කෙමිස්ට්ගේ අදහස මෙහි තැබුවෙමි .

$ find /tmp/mydir/
/tmp/mydir/
/tmp/mydir//spam
/tmp/mydir//spam/__init__.py
/tmp/mydir//spam/module.py
$ cd ~
$ python
>>> import sys
>>> sys.path.insert(0, '/tmp/mydir')
>>> from spam import module
>>> module.myfun(3)
9
>>> exit()
$ 
$ rm /tmp/mydir/spam/__init__.py*
$ 
$ python
>>> import sys
>>> sys.path.insert(0, '/tmp/mydir')
>>> from spam import module
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: No module named spam
>>> 

30

එය වෙනත් පයිතන් ගොනු ආනයනය කිරීමට පහසුකම් සපයයි. ඔබ මෙම ගොනුව වෙනත් පයි ලිපිගොනු අඩංගු නාමාවලියක (දේවල් කියන්න) තැබූ විට, ඔබට ආනයන දේවල් වැනි දෙයක් කළ හැකිය.

root\
    stuff\
         other.py

    morestuff\
         another.py

__init__.pyඩිරෙක්ටරි දේවල් තුළ මෙය නොමැතිව ඔබට වෙනත්.පී ආනයනය කළ නොහැක, මන්ද පයිතන් දේවල් සඳහා ප්‍රභව කේතය කොහේදැයි නොදන්නා නිසා එය පැකේජයක් ලෙස හඳුනාගත නොහැක.


2
මගේ ව්‍යාපෘතියේ (පයිතන් 3.4) එකම ව්‍යුහයක් මා සතුව ඇත, නමුත් මට වෙනත්.පී එකක් සෑදිය නොහැක. මම ආනයනය කළ යුත්තේ කෙසේද? root.stuff වෙතින් ආනයනය වෙනත්ද? එය VSCode නිදොස් කිරීමේ මාදිලියේ ක්‍රියාත්මක වන නමුත් විධාන රේඛාවේ නොවේ. අදහස් තිබේද?
rodrigorf

9

__init__.pyගොනුව ආනයනය පහසු කරයි. යන විට __init__.pyපැකේජයක් තුල වර්තමාන වේ, උත්සවය a()ගොනුව ආනයනය කළ හැකි b.pyනිසා වැනි:

from b import a

එය නොමැතිව, කෙසේ වෙතත්, ඔබට කෙලින්ම ආනයනය කළ නොහැක. ඔබ පද්ධති මාර්ගය සංශෝධනය කළ යුතුය:

import sys
sys.path.insert(0, 'path/to/b.py')

from b import a

1
ඔබ අදහස් කරන්නේ " a () ශ්‍රිතය b.py ගොනුවෙන් ආනයනය කළ හැකි බවයි [ස්නිපෙට්] එය නොමැතිව ඔබට කෙලින්ම ආනයනය කළ නොහැක. " මට __init__.py නොමැතිව b.py ගොනුවෙන් a () ශ්‍රිතය ආයාත කළ හැකිය.
aderchox
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.