Як написати модуль / пакет Python?


375

Я робив сценарії Python для простих завдань на роботі і ніколи не переймався упаковкою їх для використання іншими. Тепер мені призначено виготовити обгортку Python для REST API. Я абсолютно не маю уявлення про те, як почати, і мені потрібна допомога.

Що я маю:

(Просто хочу бути якомога конкретнішим) У мене готовий virtualenv , він також знаходиться в github , файл .gitignore для python також є, а також бібліотека запитів для взаємодії з API REST. Це воно.

Ось поточне дерево каталогів

.
├── bin
   └── /the usual stuff/
├── include
   └── /the usual stuff/
├── lib
   └── python2.7
       └── /the usual stuff/
├── local
   └── /the usual stuff/
└── README.md

27 directories, 280 files

Я навіть не знаю, куди помістити файли .py, якщо я коли-небудь буду їх робити.

Що я хотів зробити:

Зробіть модуль python інстальованим за допомогою "pip install ..."

Якщо можливо, я хочу загальний покроковий процес написання модулів Python.


15
Я б почав з глави 6 підручника (2.7) , або тут для 3.x Шукайте в Інтернеті підручник з модулем пітона, і ви знайдете безліч інших.
Роланд Сміт

6
Ніхто не відповів на частину
пункту

github.com/MacHu-GWU/pygitrepo-project ця бібліотека допоможе вам створити скелет проекту з нуля, а необхідна вам функція не в наявності.
MacSanhe

Відповіді:


424

Модуль - це файл, що містить визначення та висловлювання Python. Назва файлу - це ім'я модуля з суфіксом.py

Створити, hello.pyтоді записати таку функцію як її вміст:

def helloworld():
   print "hello"

Тоді ви можете імпортувати hello:

>>> import hello
>>> hello.helloworld()
'hello'
>>>

Щоб згрупувати багато .pyфайлів, покладіть їх у папку. Будь-яка папка з a __init__.pyвважається модулем python, і ви можете назвати їх пакетом

|-HelloModule
  |_ __init__.py
  |_ hellomodule.py

Ви можете перейти із заявою про імпорт на своєму модулі звичайним способом.

Для отримання додаткової інформації див. 6.4. Пакети .


7
це останнє: від імпортованого гелмомодуля HellowModule? Чи може це бути привіт у папці модулів, тож це було б з HelloModule import hello
nycynik

В даний час я граю з Python, і ця відповідь повинна бути однією з найбільш корисних, з якими я зіткнувся. Пояснює це дуже добре, дякую.
Даррен Уейнрайт

команда "встановити pip" не працюватиме, також вам потрібно буде знаходитись в одному каталозі, щоб її використовувати
Math Coder 101,

234

Python 3 - ОНОВЛЕНО 18 листопада 2015 року

Я вважаю, що прийнята відповідь корисною, але я хотів розширитись на декілька пунктів на користь інших, спираючись на власний досвід.

Модуль: Модуль - це файл, що містить визначення та висловлювання Python. Ім'я файлу - це ім'я модуля із доданим суфіксом .py.

Приклад модуля : Припустимо, у нас є один скрипт python у поточному каталозі, ось я його називаю mymodule.py

Файл mymodule.py містить такий код:

def myfunc():
    print("Hello!")

Якщо ми запускаємо інтерпретатор python3 з поточного каталогу, ми можемо імпортувати та запустити функцію myfunc такими різними способами (зазвичай ви просто виберете один із наступних):

>>> import mymodule
>>> mymodule.myfunc()
Hello!
>>> from mymodule import myfunc
>>> myfunc()
Hello!
>>> from mymodule import *
>>> myfunc()
Hello!

Гаразд, так що це було досить просто.

Тепер припустимо, що у вас є необхідність помістити цей модуль у власну спеціальну папку, щоб забезпечити простір імен модулів, а не просто запускати його ad-hoc з поточної робочої директорії. Саме тут варто пояснити концепцію пакету .

Пакет : Пакети - це спосіб структурування простору імен модулів Python за допомогою "пунктирних імен модулів". Наприклад, ім'я модуля AB позначає підмодуль з іменем B в пакеті з назвою А. Так само, як використання модулів врятує авторів різних модулів від необхідності турбуватися про глобальні імена змінних один одного, використання пунктирних імен модулів рятує авторів багатомодульних пакетів, таких як NumPy або бібліотека зображень Python, не турбуючись про імена модулів один одного.

Приклад пакету : Припустимо, у нас є наступна папка та файли. Тут mymodule.py ідентичний раніше, а __init__.py - порожній файл:

.
└── mypackage
    ├── __init__.py
    └── mymodule.py

Файли __init__.py необхідні, щоб Python трактував каталоги як пакунки, що містять пакунки. Для отримання додаткової інформації перегляньте посилання на документацію модулів, надане пізніше.

Наш поточний робочий каталог знаходиться на один рівень вище звичайної папки під назвою mypackage

$ ls
mypackage

Якщо ми зараз запустимо інтерпретатор python3, ми можемо імпортувати та запустити модуль mymodule.py, що містить необхідну функцію myfunc, такими різними способами (зазвичай ви просто виберете один із наступних):

>>> import mypackage
>>> from mypackage import mymodule
>>> mymodule.myfunc()
Hello!
>>> import mypackage.mymodule
>>> mypackage.mymodule.myfunc()
Hello!
>>> from mypackage import mymodule
>>> mymodule.myfunc()
Hello!
>>> from mypackage.mymodule import myfunc
>>> myfunc()
Hello!
>>> from mypackage.mymodule import *
>>> myfunc()
Hello!

Якщо припустити Python 3, є чудова документація за адресою: Модулі

Що стосується умов іменування пакетів та модулів, загальні вказівки наведені в PEP-0008 - див. Назви пакетів та модулів

Модулі повинні мати короткі, малі імена. Підкреслення можна використовувати у назві модуля, якщо це покращує читабельність. Пакети Python також повинні мати короткі, малі імена, хоча використання підкреслення не рекомендується.


5
Приємне просте пояснення. Що робити, якщо ви хочете зберегти іншу папку всередині свого пакунка?
Ануй Гупта

3
Включити повністю залежить від того, що ви написали. У випадку, якщо ви розмістите речі поза функцією на своєму модулі, ви запускаєте його під час подібного дзвінка import mypackage. У випадку, якщо ви хочете імпортувати лише функцію з модуля (навіть файлу), краще використовувати from module import function. У випадку підпапки, from subfolder.module import functionщоб ви могли просто зателефонувати function()без загоряння інших деталей коду. Крім того, не використовуйте, from module import *якщо вам це не дуже потрібно.
м3нда

5
Залишилося тільки питання - як я можу отримати пакет, щоб імпортувати все import mypackage? Додавання import mymoduleдо __init__.pyне працює ..
576i

Акуратне пояснення! однак у мене виникає питання, чи є numpy пакетом, як я можу виконати numpy.cos (1) у своєму інтерпретаторі, тому що, здається, назва модуля між ними пропущена. Ні?
користувач1935724

3
Як щодо піп?
whackamadoodle3000

199

Оскільки цього питання ОП ще ніхто не висвітлював:

Що я хотів зробити:

Зробіть модуль python інстальованим за допомогою "pip install ..."

Ось абсолютний мінімальний приклад, який показує основні етапи підготовки та завантаження вашого пакету до PyPI за допомогою setuptoolsта twine.

Це аж ніяк не замінює прочитання принаймні навчального посібника , його набагато більше, ніж висвітлено в цьому самому базовому прикладі.

Створення самого пакету вже охоплене іншими відповідями, тож припустимо, що ми охопили цей крок і нашу структуру проекту так:

.
└── hellostackoverflow/
    ├── __init__.py
    └── hellostackoverflow.py

Для того, щоб використовувати setuptoolsдля упаковки, нам потрібно додати файл setup.py, який йде в кореневу папку нашого проекту:

.
├── setup.py
└── hellostackoverflow/
    ├── __init__.py
    └── hellostackoverflow.py

Як мінімум, ми вказуємо метадані нашого пакету, наші setup.pyвиглядатимуть так:

from setuptools import setup

setup(
    name='hellostackoverflow',
    version='0.0.1',
    description='a pip-installable package example',
    license='MIT',
    packages=['hellostackoverflow'],
    author='Benjamin Gerfelder',
    author_email='benjamin.gerfelder@gmail.com',
    keywords=['example'],
    url='https://github.com/bgse/hellostackoverflow'
)

Оскільки ми встановили license='MIT', ми включаємо в наш проект копію LICENCE.txt, поряд з файлом readme в reStructuredText як README.rst:

.
├── LICENCE.txt
├── README.rst
├── setup.py
└── hellostackoverflow/
    ├── __init__.py
    └── hellostackoverflow.py

На даний момент ми готові перейти до упаковки, використовуючи setuptools, якщо у нас її вже не встановлено, ми можемо встановити її за допомогою pip:

pip install setuptools

Для того, щоб це зробити і створити source distribution, у кореневій папці нашого проекту ми викликаємо наш setup.pyкомандний рядок із зазначенням, що ми хочемо sdist:

python setup.py sdist

Це створить наш дистрибутивний пакунок та інформацію про яйця та призведе до такої структури папки з нашим пакетом у dist:

.
├── dist/
├── hellostackoverflow.egg-info/
├── LICENCE.txt
├── README.rst
├── setup.py
└── hellostackoverflow/
    ├── __init__.py
    └── hellostackoverflow.py

На даний момент у нас є пакет, який ми можемо встановити, використовуючи pip, таким чином, з нашого кореня проекту (якщо у вас є всі назви, як у цьому прикладі):

pip install ./dist/hellostackoverflow-0.0.1.tar.gz

Якщо все піде добре, тепер ми можемо відкрити інтерпретатора Python, я б сказав десь за межами нашого каталогу проектів, щоб уникнути плутанини, і спробувати використовувати наш новий блискучий пакет:

Python 3.5.2 (default, Sep 14 2017, 22:51:06) 
[GCC 5.4.0 20160609] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from hellostackoverflow import hellostackoverflow
>>> hellostackoverflow.greeting()
'Hello Stack Overflow!'

Тепер, коли ми підтвердили, що пакет встановлюється та працює, ми можемо завантажити його в PyPI.

Оскільки ми не хочемо забруднювати реальний сховище своїми експериментами, ми створюємо обліковий запис для тестового сховища та встановлюємо twineдля процесу завантаження:

pip install twine

Зараз ми майже там, з нашим створеним обліковим записом ми просто кажемо twineзавантажити наш пакет, він попросить наші облікові дані та завантажить наш пакунок у вказане сховище:

twine upload --repository-url https://test.pypi.org/legacy/ dist/*

Тепер ми можемо увійти до нашого облікового запису в тестовому сховищі PyPI і дивуватися нашому щойно завантаженому пакету на деякий час, а потім захопити його за допомогою pip:

pip install --index-url https://test.pypi.org/simple/ hellostackoverflow

Як ми бачимо, основний процес не дуже складний. Як я вже говорив раніше, тут є набагато більше, ніж тут висвітлено, тому заздалегідь читайте підручник для більш поглибленого пояснення.


Чи буде опублікований мій пакет відразу після setuptools?
U10-Вперед

@ U9-Forward Ні, публікація виконується за допомогою twine, але ви можете протестувати свій пакет локально перед публікацією після того, як ви створили його setuptools.
bgse

9

Визначивши вибрані команди, ви можете просто перетягнути збережений файл у папку Lib у ваших програмних файлах python.

>>> import mymodule 
>>> mymodule.myfunc()

2

Створіть файл під назвою "hello.py"

Якщо ви використовуєте Python 2.x

def func():
    print "Hello"

Якщо ви використовуєте Python 3.x

def func():
    print("Hello")

Запустіть файл. Потім ви можете спробувати наступне:

>>> import hello
>>> hello.func()
Hello

Якщо ви хочете трохи важко, можете скористатися наступним:

Якщо ви використовуєте Python 2.x

def say(text):
    print text

Якщо ви використовуєте Python 3.x

def say(text):
    print(text)

Бачите ту, що в дужках поруч із визначенням? Це важливо. Це той, який ви можете використовувати в межах визначення.

Текст - Ви можете використовувати його, коли програма хоче сказати, що ви хочете. За своєю назвою це текст. Сподіваюся, ви знаєте, що означає текст. Це означає "слова" або "речення".

Запустіть файл. Потім ви можете спробувати наступне, якщо ви використовуєте Python 3.x:

>>> import hello
>>> hello.say("hi")
hi
>>> from hello import say
>>> say("test")
test

Для Python 2.x - я думаю, те саме, що і з Python 3? Не маю уявлення. Виправте мене, якщо я помилився на Python 2.x (я знаю Python 2, але я використовуюсь з Python 3)


2

Я створив проект, щоб легко ініціювати скелет проекту з нуля . https://github.com/MacHu-GWU/pygitrepo-project .

І ви можете створити тестовий проект, скажімо, learn_creating_py_package .

Ви можете дізнатися, який компонент у вас повинен бути для різних цілей, наприклад :

  • створити віртуаленв
  • встановити себе
  • запустити unittest
  • запустити покриття коду
  • скласти документ
  • розгортати документ
  • запустити unittest у різній версії python
  • розгорнути до PYPI

Перевага використання в pygitrepoтому , що ці утомливо автоматично створюються себе і адаптувати ваші package_name, project_name, github_account, document host service, windows or macos or linux.

Це гарне місце, щоб навчитися розробляти проект пітона як професіонал.

Сподіваюся, це може допомогти.

Дякую.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.