如何访问Python包中的顶级文件代码

0 投票
3 回答
945 浏览
提问于 2025-04-18 10:58

我有一个Python 2.7的包,结构是这样的:

hdl/
    __init__.py
    run_job.py
    other_stuff/
        __init__.py
        other_files/
setup.py
scripts/
    client.py

run_job.py文件里面包含:

def run_job():
    pass

这里没有任何类。其实,这个代码库里根本没有类;我是继承过来的。

我该如何从这个包的客户端执行run_job()函数呢?

(现在,run_job()函数在__init__.py里,我对此一点也不喜欢。)

我在__init__.py里放了这些:

import hdl.run_job

import run_job

无论如何,我都收到了No module named run_job的错误。如果我完全不导入,客户端代码会显示'module' object has no attribute 'run_job'或者name 'run_job' is not defined,这取决于我做了哪一步:

import hdl
hdl.run_job

import hdl
run_job

我的setup.py文件:

from setuptools import setup
from setuptools import find_packages
from os import walk, path

install_requires = [
    "ecdsa==0.11",
    "importlib==1.0.3",
    "paramiko==1.13.0",
    "pyasn1==0.1.7",
    "pycrypto==2.6.1",
    "wsgiref==0.1.2",
]

script_base = "scripts"
my_path = path.dirname(path.abspath(__file__))
walk_path = path.join(my_path, script_base)
for(_, _, filenames) in walk(walk_path):
    scripts = [("%s/%s"  % (script_base, f)) for f in filenames]
    break

setup(
    name="hdl",
    version="dev",
    description="HDL",
    url="http://example.com",
    long_description="HDLA",
    author="heh",
    author_email=".com",
    maintainer="foo",
    maintainer_email=".com",
    license="Proprietary",
    packages=find_packages(exclude=("tests",)),
    test_suite="nose.collector",
    include_package_data=True,
    package_data = {'': [ '*.csv', '*.hql', '*.pig', '*.sh', '*.sql' ]},
    install_requires=install_requires,
    zip_safe=False,
    classifiers=[
        "Development Status :: 2 - Alpha",
        "Environment :: Command Line",
        "Framework :: None",
        "Intended Audience :: Developers",
        "Intended Audience :: System Administrators",
        "License :: Other/Proprietary License",
        "Natural Language :: English",
        "Operating System :: MacOS :: MacOS X",
        "Operating System :: POSIX :: Linux",
        "Programming Language :: Python :: 2.7",
        "Topic :: Software Development",
        "Topic :: ETL"
    ],
    scripts=scripts,
)

如果我把run_job函数放在__init__.py里,它就能正常工作: import hdl hdl.run_job()

3 个回答

0

这个文件的名字不是 run_job.py,而是其他的名字。。把名字改对了,所有东西就能正常工作了。

其他的回答都是对的;把 __init__.py 留空,然后在 client.py 里这样写:

from hdl import run_job
run_job.run_job()

或者

from hdl.run_job import run_job
run_job()

或者把这个放在 __init__.py 里:

from .run_job import run_job

然后在 client.py 里写这个:

import hdl
hdl.run_job() # won't work
3

你的客户端代码需要先写 from hdl import run_job,然后再调用 run_job.run_job(),或者(可能更容易理解)写 from hdl.run_job import run_job

如果你想让用户可以直接使用 run_job,也就是说不需要先导入 run_job 模块就能使用这个函数,那么在你的顶层文件 __init__.py 中写 from .run_job import run_job。这样用户就可以直接写 import hdl,然后使用 hdl.run_job

2

把下面的内容放到 __init__.py 文件里:

__all__ = ["run_job"]

在你的客户端代码里:

from hdl import run_job
run_job.run_job()

在你的 setup.py 文件中,"scripts" 这个变量没有定义,所以我把下面这行去掉了:

scripts=scripts,

之后我运行了 "sudo python setup.py install",然后用客户端测试了一下:

$ python
Python 2.7.6 (default, Mar 22 2014, 17:40:27) 
[GCC 4.8.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from hdl import run_job
>>> run_job.run_job()
>>> 

一切正常。

再试试别的事情:

pydoc hdl

检查一下生成的文档中提供的路径是否指向正确的位置。

Help on package hdl:

NAME
    hdl

FILE
    <path-to-hdl>/hdl/__init__.py

PACKAGE CONTENTS
    run_job

所以,我的文件结构和你的完全一样,setup.py 文件内容也一样。下面是文件的内容,在我的电脑上可以正常工作。仔细对比一下你这边的,确保 "setup.py install" 没有任何错误。如果 pydoc 没有显示任何内容,说明 hdl 没有安装成功。

==========
run_job.py
=========== 
def run_job():
    pass

============ client.py ===========

from hdl import run_job
run_job.run_job()

============ setup.py ===========

和你的完全一样

撰写回答