Como escrever um módulo / pacote Python?

375

Eu tenho feito scripts Python para tarefas simples no trabalho e nunca me incomodei em empacotá-los para que outros usem. Agora fui designado para criar um wrapper Python para uma API REST. Não tenho absolutamente nenhuma idéia de como começar e preciso de ajuda.

O que eu tenho:

(Só quero ser o mais específico possível) Eu tenho o virtualenv pronto, também está no github , o arquivo .gitignore para python também está lá, além disso, a biblioteca de solicitações para interagir com a API REST. É isso aí.

Aqui está a árvore de diretórios atual

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

27 directories, 280 files

Nem sei onde colocar os arquivos .py, se algum dia eu fizer um.

O que eu queria fazer:

Torne um módulo python instalável com "pip install ..."

Se possível, quero um processo geral passo a passo para escrever módulos Python.

yowmamasita
fonte
15
Eu começaria com o capítulo 6 do tutorial (2.7) , ou aqui com a versão 3.x Pesquise na Internet o tutorial do módulo python e você encontrará muitos outros.
Roland Smith
6
Ninguém respondeu a parte do pip #
whackamadoodle3000 17/17/17
github.com/MacHu-GWU/pygitrepo-project Esta biblioteca ajuda você a criar o esqueleto do projeto a partir do zero, e o recurso que você precisa está fora da caixa.
MacSanhe 02/08/19

Respostas:

424

Um módulo é um arquivo que contém definições e instruções Python. O nome do arquivo é o nome do módulo com o sufixo.py

crie hello.pye escreva a seguinte função como seu conteúdo:

def helloworld():
   print "hello"

Então você pode importar hello:

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

Para agrupar muitos .pyarquivos, coloque-os em uma pasta. Qualquer pasta com um __init__.pyé considerada um módulo por python e você pode chamá-los de pacote

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

Você pode continuar com a declaração de importação no seu módulo da maneira usual.

Para mais informações, consulte 6.4. Pacotes .

Anuj
fonte
7
seria o último: do HellowModule import hellomodule? Poderia ser Olá na pasta módulo, de modo que seria de HelloModule Olá importação
nycynik
Atualmente brincando com o Python e esta resposta deve ser uma das mais úteis que já encontrei. Explica muito bem, obrigado.
Darren Wainwright
o comando "pip install" não funcionará, você também deve estar no mesmo diretório para usá-lo
Math Coder 101
234

Python 3 - ATUALIZADO 18 de novembro de 2015

Achei a resposta aceita útil, mas desejei expandir vários pontos em benefício de outros, com base em minhas próprias experiências.

Módulo: Um módulo é um arquivo que contém definições e instruções Python. O nome do arquivo é o nome do módulo com o sufixo .py anexado.

Exemplo de módulo : Suponha que tenhamos um único script python no diretório atual, aqui estou chamando-o mymodule.py

O arquivo mymodule.py contém o seguinte código:

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

Se executarmos o interpretador python3 a partir do diretório atual, poderemos importar e executar a função myfunc das seguintes maneiras diferentes (você normalmente escolheria uma das seguintes opções):

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

Ok, então isso foi fácil o suficiente.

Agora, suponha que você precise colocar este módulo em sua própria pasta dedicada para fornecer um espaço para nome do módulo, em vez de apenas executá-lo ad-hoc no diretório de trabalho atual. É aqui que vale a pena explicar o conceito de pacote .

Pacote : Pacotes são uma maneira de estruturar o espaço de nome do módulo do Python usando “nomes de módulo pontilhado”. Por exemplo, o nome do módulo AB designa um submódulo chamado B em um pacote chamado A. Assim como o uso de módulos evita que os autores de módulos diferentes se preocupem com os nomes de variáveis ​​globais um do outro, o uso de nomes de módulo pontilhado salva os autores de pacotes com vários módulos, como o NumPy ou a Python Imaging Library, de se preocupar com os nomes dos módulos um do outro.

Exemplo de pacote : Vamos agora assumir que temos a seguinte pasta e arquivos. Aqui, mymodule.py é idêntico a antes e __init__.py é um arquivo vazio:

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

Os arquivos __init__.py são necessários para fazer o Python tratar os diretórios como contendo pacotes. Para mais informações, consulte o link da documentação dos Módulos, fornecido posteriormente.

Nosso diretório de trabalho atual está um nível acima da pasta comum chamada mypackage

$ ls
mypackage

Se rodarmos o interpretador python3 agora, poderemos importar e executar o módulo mymodule.py que contém a função necessária myfunc das seguintes maneiras diferentes (você normalmente escolheria uma das seguintes opções):

>>> 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!

Supondo que o Python 3, haja excelente documentação em: Módulos

Em termos de convenções de nomenclatura para pacotes e módulos, as diretrizes gerais são fornecidas em PEP-0008 - consulte Nomes de Pacotes e Módulos

Os módulos devem ter nomes curtos e todos em minúsculas. Sublinhados podem ser usados ​​no nome do módulo se melhorar a legibilidade. Os pacotes Python também devem ter nomes curtos, todos em minúsculas, embora o uso de sublinhados seja desencorajado.

arcseldon
fonte
5
Boa explicação simples. E se você quiser manter outra pasta dentro do mypackage?
Anuj Gupta
3
A inclusão depende totalmente do que você escreveu. No caso de você colocar coisas fora de uma função em seu módulo, você as acionará quando chamar como import mypackage. No caso de você querer importar apenas uma função de um módulo (mesmo um arquivo), é melhor usar from module import function. No caso de uma subpasta from subfolder.module import function, você pode simplesmente chamar sem function()disparar outras partes do código. Além disso, não use from module import *se você realmente não precisa.
M3nda
5
A única questão que resta é como posso obter o pacote para importar tudo import mypackage? Adicionando import mymodulea __init__.pynão funciona ..
576i
Explicação pura! no entanto, tenho uma dúvida se numpy é um pacote, como posso executar o numpy.cos (1) no meu intérprete, porque esse parece ser um nome de módulo no meio do caminho. Não?
User1935724 de
3
Que tal pip?
Whackamadoodle3000
199

Como ninguém cobriu ainda esta questão do OP:

O que eu queria fazer:

Torne um módulo python instalável com "pip install ..."

Aqui está um exemplo mínimo absoluto, mostrando as etapas básicas de preparação e upload do seu pacote para o PyPI usando setuptoolse twine.

Isso não substitui a leitura de pelo menos o tutorial ; há muito mais do que abordado neste exemplo muito básico.

A criação do pacote em si já é abordada por outras respostas aqui, portanto, vamos assumir que temos essa etapa coberta e nossa estrutura de projeto como esta:

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

Para usar setuptoolsno empacotamento, precisamos adicionar um arquivo setup.py, que vai para a pasta raiz do nosso projeto:

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

No mínimo, especificamos os metadados para o nosso pacote, e setup.pyficaria assim:

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'
)

Desde que configuramos license='MIT', incluímos uma cópia em nosso projeto como LICENCE.txt, juntamente com um arquivo leia-me em reStructuredText como README.rst:

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

Neste ponto, estamos prontos para começar a empacotar usando setuptools, se ainda não o tivermos instalado, podemos instalá-lo com pip:

pip install setuptools

Para fazer isso e criar uma source distribution, em nossa pasta raiz do projeto, chamamos nossa a setup.pypartir da linha de comando, especificando que queremos sdist:

python setup.py sdist

Isso criará nosso pacote de distribuição e informações sobre o ovo e resultará em uma estrutura de pastas como esta, com nosso pacote em dist:

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

Neste ponto, temos um pacote que podemos instalar usando pip, portanto, a partir da raiz do nosso projeto (assumindo que você tenha toda a nomeação como neste exemplo):

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

Se tudo correr bem, agora podemos abrir um intérprete Python, eu diria em algum lugar fora do diretório do projeto para evitar qualquer confusão e tentar usar nosso novo pacote:

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!'

Agora que confirmamos a instalação e o funcionamento do pacote, podemos carregá-lo no PyPI.

Como não queremos poluir o repositório ativo com nossos experimentos, criamos uma conta para o repositório de teste e instalamos twineo processo de upload:

pip install twine

Agora estamos quase lá, com a nossa conta criada, simplesmente pedimos twinepara fazer o upload do nosso pacote, ele solicitará nossas credenciais e fará o upload do pacote no repositório especificado:

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

Agora podemos fazer login em nossa conta no repositório de teste do PyPI e nos maravilhar com nosso pacote recém-carregado por um tempo, e depois pegá-lo usando pip:

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

Como podemos ver, o processo básico não é muito complicado. Como eu disse anteriormente, há muito mais do que o abordado aqui, então vá em frente e leia o tutorial para obter uma explicação mais aprofundada.

bgse
fonte
Meu pacote será publicado logo após setuptools?
Sub-Forward
@ U9-Forward Não, a publicação está concluída twine, mas você pode testar seu pacote localmente antes de publicar depois de criá-lo setuptools.
Bgse # 6/19
9

Depois de definir os comandos escolhidos, você pode simplesmente arrastar e soltar o arquivo salvo na pasta Lib nos seus arquivos de programa python.

>>> import mymodule 
>>> mymodule.myfunc()
Dreamatronix
fonte
2

Crie um arquivo chamado "hello.py"

Se você estiver usando o Python 2.x

def func():
    print "Hello"

Se você estiver usando o Python 3.x

def func():
    print("Hello")

Execute o arquivo Em seguida, você pode tentar o seguinte:

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

Se você quiser um pouco mais, pode usar o seguinte:

Se você estiver usando o Python 2.x

def say(text):
    print text

Se você estiver usando o Python 3.x

def say(text):
    print(text)

Veja aquele entre parênteses ao lado do define? Aquilo é importante. É o que você pode usar dentro da definição.

Texto - Você pode usá-lo quando quiser que o programa diga o que deseja. De acordo com o nome, é texto. Espero que você saiba o que significa texto. Significa "palavras" ou "frases".

Execute o arquivo Em seguida, você pode tentar o seguinte se estiver usando o Python 3.x:

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

Para Python 2.x - acho que a mesma coisa com Python 3? Nenhuma idéia. Corrija-me se eu cometer um erro no Python 2.x (eu conheço o Python 2, mas estou acostumado com o Python 3)

Kakkoiikun
fonte
2

Criei um projeto para iniciar facilmente um esqueleto do projeto a partir do zero . https://github.com/MacHu-GWU/pygitrepo-project .

E você pode criar um projeto de teste, digamos learn_creating_py_package,.

Você pode aprender qual componente deve ter para diferentes fins, como :

  • criar virtualenv
  • instalar-se
  • correr mais unittest
  • executar cobertura de código
  • construir documento
  • implantar documento
  • executar unittest em diferentes versões python
  • implantar no PYPI

A vantagem de usar pygitrepoé que esses tedioso são criados automaticamente em si e adaptar o seu package_name, project_name, github_account, document host service, windows or macos or linux.

É um bom lugar para aprender a desenvolver um projeto python como um profissional.

Espero que isso possa ajudar.

Obrigado.

MacSanhe
fonte