简体   繁体   English

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

[英]How to access code in a top-level file in a python package

I have a Python 2.7 package laid out like this: 我有一个如下所示的Python 2.7包:

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

run_job.py contains: run_job.py包含:

def run_job():
    pass

There is no class. 没有课。 Actually, there are no classes anywhere in this codebase; 实际上,此代码库中的任何地方都没有任何类。 I inherited it. 我继承了它。

How do I execute the run_job() function from clients of this package? 如何从此程序包的客户端执行run_job()函数?

(Right now, the run_job() function lives in __init__.py , which I don't like at all.) (现在,run_job()函数位于__init__.py ,我一点都不喜欢。)

I put these in __init__.py : 我把它们放在__init__.py

import hdl.run_job

import run_job

Either way, I get No module named run_job . 无论哪种方式,我都No module named run_job得到No module named run_job If I leave off the import entirely, the client code says either 'module' object has no attribute 'run_job' or name 'run_job' is not defined , depending on which of these I do: 如果我完全取消导入,则客户端代码会说'module' object has no attribute 'run_job'name 'run_job' is not defined ,具体取决于我要执行的操作:

import hdl
hdl.run_job

import hdl
run_job

My setup.py : 我的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,
)

If I stick the run_job function in __init__.py it works fine: import hdl hdl.run_job() 如果我将run_job函数粘贴在__init__.py则可以正常工作:导入hdl hdl.run_job()

Put the following in __init__.py : 将以下内容放在__init__.py

__all__ = ["run_job"]

In your client: 在您的客户中:

from hdl import run_job
run_job.run_job()

in your setup.py "scripts" variable is not defined, so I had to remove the following string: 在您的setup.py“脚本”变量中未定义,因此我必须删除以下字符串:

scripts=scripts, 脚本=脚本,

After that I ran "sudo python setup.py install" and tested it with the client: 之后,我运行“ 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()
>>> 

Everything works. 一切正常。 Try yet another thing: 再尝试一件事:

pydoc hdl

Check if the path provided in the generated doc refers to the right location. 检查生成的文档中提供的路径是否指向正确的位置。

Help on package hdl:

NAME
    hdl

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

PACKAGE CONTENTS
    run_job

So, I have exactly the same layout and setup.py file as yours. 因此,我的布局和setup.py文件与您的完全相同。 Below is the content of files and it works on my comp. 以下是文件的内容,可以在我的电脑上使用。 Try to carefully compare with what you have and make sure that "setup.py install" doesn't have any errors. 尝试仔细比较您所拥有的,并确保“ setup.py install”没有任何错误。 If pydoc doesn't show anything, hdl was not installed. 如果pydoc不显示任何内容,则说明未安装hdl。

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

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

from hdl import run_job
run_job.run_job()

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

exactly as yours 和你一样

Your client code needs to do from hdl import run_job and then do run_job.run_job() , or (probably more readable) from hdl.run_job import run_job . 您的客户端代码需要from hdl import run_job ,然后执行run_job.run_job() ,或者from hdl.run_job import run_job (可能更具可读性) from hdl.run_job import run_job

If you want to provide "top level" access to run_job (that is, not require users to import the run_job module to get the run_job function), then in your top-level __init__.py do from .run_job import run_job . 如果要提供对run_job “顶级”访问run_job (即,不要求用户导入run_job模块以获取run_job函数),则在顶级__init__.pyfrom .run_job import run_job Then clients can do import hdl and later use hdl.run_job . 然后,客户端可以import hdl ,以后再使用hdl.run_job

The file wasn't named run_job.py it was named something else. 该文件的名称不是run_job.py ,而是其他名称。 Sigh . 叹了口气 Fixing the name causes everything to work. 固定名称会使一切正常。

The other answers are correct; 其他答案是正确的。 leave the __init__.py empty and in client.py do this: __init__.py保留为空,并在client.py执行以下操作:

from hdl import run_job
run_job.run_job()

or 要么

from hdl.run_job import run_job
run_job()

or put this in __init__.py : 或将其放在__init__.py

from .run_job import run_job

and this in client.py : 这在client.py

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM