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

Я делал скрипты 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.

Ответ 1

Модуль - это файл, содержащий определения и операторы 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. Пакеты

Ответ 2

Python 3 - ОБНОВЛЕНО 18 ноября 2015 г.

Нашел признанный ответ полезным, но хотел бы расширить несколько пунктов в интересах других, основываясь на моем собственном опыте.

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

Пример модуля. Предположим, что в текущем каталоге есть один python script, здесь я называю его 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 из текущего рабочего каталога. Именно здесь стоит объяснить концепцию пакета.

Пакет. Пакеты - это способ структурирования пространства имен модулей Pythons с использованием имен "пунктирных модулей". Например, имя модуля 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 имеет отличную документацию по адресу: Modules

В терминах соглашений об именах для пакетов и модулей общие рекомендации приведены в PEP-0008 - см. Имена пакетов и модулей

Модули должны иметь короткие, все строчные имена. Подчеркивания могут использоваться в имени модуля, если это улучшает читаемость. Пакеты Python также должны иметь короткие имена всех строчных букв, хотя использование подчеркиваний не рекомендуется.

Ответ 3

Так как никто еще не закрывал этот вопрос OP:

Что я хотел сделать:

Создайте модуль 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='[email protected]',
    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

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

Ответ 4

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

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

Ответ 5

Сделайте файл с именем "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)

Ответ 6

Я создал проект, чтобы легко инициировать скелет проекта с нуля. 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, как профессионал.

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

Спасибо.