【发布时间】:2021-06-28 02:07:29
【问题描述】:
我希望有以下目录结构:
project_name (unfortunate, I did not think to name the git repo something different)
| ...
|
|--project_name
| |-- __init__.py
| |-- module1
| | |-- __init__.py
| | |-- pyfile1.py
| | #contains class1 which pulls from class2 and class1
| |-- module2
| | |-- __init__.py
| | |-- pyfile2.py
| | #contains class2
| |-- module3
| |-- __init__.py
| |-- pyfile3.py
| #contains class3
|--tests
| |--test1
...
上面,当我把它扔到 github 并从 github 安装它时,我注意到子模块是单独安装的,而不是在 project_name 下一起安装。
我想简洁地访问第 1 类,而第 1 类从第 2 类和第 3 类中提取。目前,我让他们互相调用很好,我相信他们正在通过我的测试目录中包含的 pytest 进行测试。即……
# in class1
from project_name.module2.pyfile2 import class2
from project_name.module3.pyfile3 import class3
# in test1
from project_name.module1.pyfile1 import class1
我希望能够像 from project_name.module1 import class1 一样调用说 class1 还是必须在此结构下使用 from project_name.module1.pyfile1 import class1?我知道这可能有点荒谬,但我已经尝试了一些组织迭代,即删除子模块结构并简单地将它们全部放在 project_name 下,并带有一个 __init__.py。但我现在想要某种关注点分离,所以我想知道如何正确地做到这一点。
我认为是多个__init__.pys 导致单独的模块与我的setup.py 一起安装,它正在查看project_name 目录,而不是仅仅安装project_name 目录,然后我可以访问像我对测试所做的子模块:
import setuptools
import re
import os.path
import sys
with open("README.md", "r") as fh:
long_description = fh.read()
def read(filename):
return open(os.path.join(os.path.dirname(__file__), filename)).read()
version = re.search(r'^__version__\s*=\s*[\'"]([^\'"]*)[\'"]', read('project_one/__init__.py'), re.MULTILINE).group(1)
install_requires=['pandas>=1.0.0']
include_packages=['project_one']
tests_require=['pytest>4.0', 'pytest-pylint']
setup_requires=['pytest-runner', 'pytest-pylint']
setuptools.setup(
name="project_one"
, version=version
, license='LICENSE.txt'
, author=author
, author_email=email
, description=description
, long_description=long_description
, long_description_content_type="text/markdown"
, url=url
, packages=setuptools.find_packages('project_name', exclude=['tests'])
, classifiers=[
'Development Status :: 3 - Alpha',
'Intended Audience :: Developers',
'Topic :: Software Development :: Build Tools',
'License :: OSI Approved :: MIT License',
'Programming Language :: Python :: 3.6',
'Programming Language :: Python :: 3.7',
'Programming Language :: Python :: 3.8',
]
, python_requires='>3.0, !=3.1.*, !=3.2.*, !=3.3.*'
, install_requires=install_requires
, tests_require=tests_require
, setup_requires=setup_requires
#, extras_require={'pandas': ['pandas>=0.14.0']}
)
那么我该如何停止子目录的安装,让它安装 project_name 目录,并正确地构建目录和代码来做到这一点。
另外,我的子目录__init__.py 是空的。 project_name 的__init__.py 有以下内容,但如果没有安装project_name 目录,则无用:
# -*- coding: utf-8 -*-
# PEP 8 Style Guide for Python Code.
# https://www.python.org/dev/peps/pep-0008/
import logging
# Major.Minor.Patch
__version__ = '0.7.0'
__author__ = 'name'
from .module1.pyfile1 import class1
from .module2.pyfile2 import class2
from .module1.pyfile3 import class3
# Set default logging handler to avoid "No handler found" warnings.
try: # Python 2.7+
from logging import NullHandler
except ImportError:
class NullHandler(logging.Handler):
"""For future error handling purposes"""
def emit(self, record):
pass
logging.getLogger(__name__).addHandler(NullHandler())
【问题讨论】:
-
澄清一些命名:Python 文件是一个模块,带有
__init__.py的文件夹是一个包。 -
感谢您的更正,这很有帮助。在这些方面更有意义......这三个包正在安装在站点包中。
标签: python python-3.x pip anaconda