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

375

Я делал скрипты Python для простых задач на работе и никогда не задумывался о том, чтобы их упаковывать для других. Теперь мне поручено сделать оболочку Python для REST API. Я абсолютно не знаю, с чего начать, и мне нужна помощь.

Что я имею:

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

Вот текущее дерево каталогов

.
├── 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.

yowmamasita
источник
15
Я бы начал с главы 6 урока (2.7) или здесь с 3.x Ищите в интернете учебник по модулю Python, и вы найдете множество других.
Роланд Смит
6
Никто не ответил на часть пипа
whackamadoodle3000
github.com/MacHu-GWU/pygitrepo-project. Эта библиотека поможет вам создать проектный скелет с нуля, а необходимая вам функция уже готова.
MacSanhe

Ответы:

424

Модуль - это файл, содержащий определения и операторы Python. Имя файла - это имя модуля с суффиксом.py

создать, а hello.pyзатем написать следующую функцию в качестве его содержимого:

def helloworld():
   print "hello"

Затем вы можете импортировать hello:

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

Чтобы сгруппировать много .pyфайлов, поместите их в папку. Любая папка с __init__.pyмодулем Python считается модулем, и вы можете назвать их пакетом.

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

Вы можете использовать оператор импорта в вашем модуле обычным способом.

Для получения дополнительной информации см. 6.4. Пакеты .

Ануй
источник
7
будет ли последний: из HellowModule импортировать hellomodule? Может ли это быть привет в папке модуля, так что это будет из импорта HelloModule привет
nycynik
В настоящее время играю с Python, и этот ответ должен быть одним из самых полезных, с которыми я сталкивался. Объясняет это очень хорошо, спасибо.
Даррен Уэйнрайт
команда "pip install" не будет работать, также вы должны быть в той же директории, чтобы ее использовать
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 в пакете с именем A. Так же, как использование модулей избавляет авторов различных модулей от необходимости беспокоиться о именах глобальных переменных друг друга, использование названий модулей с точками сохраняет авторов мультимодульных пакетов, таких как NumPy или Python Imaging Library от необходимости беспокоиться об именах модулей друг друга.

Пример пакета : теперь давайте предположим, что у нас есть следующая папка и файлы. Здесь 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 также должны иметь короткие, строчные имена, хотя использование подчеркивания не рекомендуется.

arcseldon
источник
5
Хорошее простое объяснение. Что если вы хотите сохранить другую папку внутри mypackage?
Анудж Гупта
3
Включение полностью зависит от того, что вы написали. В случае, если вы поместите материал вне функции в вашем модуле, вы запустите его при вызове like import mypackage. В случае, если вы хотите импортировать только функцию из модуля (даже файла), лучше использовать from module import function. В случае подпапки, from subfolder.module import functionтак что вы можете просто вызвать без function()запуска других частей кода. Кроме того, не используйте, from module import *если вам действительно не нужно.
m3nda
5
Остался только один вопрос: как мне получить пакет для импорта всего import mypackage? Добавление import mymoduleк __init__.pyне работает ..
576i
Аккуратное объяснение! Тем не менее, у меня есть вопрос, если numpy - это пакет, как я могу выполнить numpy.cos (1) в моем интерпретаторе, потому что между ними, похоже, отсутствует имя модуля. Нет?
user1935724
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

Это создаст наш дистрибутивный пакет и egg-info, и в результате мы получим структуру папок, подобную этой, с нашим пакетом в 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

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

bgse
источник
Будет ли моя посылка опубликована сразу после setuptools?
U10-Форвард
@ U9-Forward Нет, публикация завершена twine, но вы можете проверить свой пакет локально перед публикацией после того, как создали его с помощью setuptools.
19
9

После того, как вы определили выбранные вами команды, вы можете просто перетащить сохраненный файл в папку Lib в ваших программных файлах python.

>>> import mymodule 
>>> mymodule.myfunc()
Dreamatronix
источник
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)

Kakkoiikun
источник
2

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

И вы можете создать тестовый проект, скажем , давайте, learn_creating_py_package.

Вы можете узнать, какой компонент вы должны иметь для различных целей, таких как :

  • создать virtualenv
  • установить себя
  • запустить юнит-тест
  • запуск кода покрытия
  • построить документ
  • развернуть документ
  • запустить unittest в другой версии Python
  • развернуть в PYPI

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

Это хорошее место, чтобы научиться разрабатывать проект на Python, как профессионал.

Надеюсь, это поможет.

Спасибо.

MacSanhe
источник