简体   繁体   English

如何使python文件可作为脚本运行并且可作为包导入?

[英]How can I make a python file runnable as a script and importable as a package?

I'm still trying to get a hang of python 3 and I'm running into an issue where I can either run a .py file as a script or import it as a module, but not both. 我仍然想摆脱python 3的困扰,遇到了一个问题,我可以将.py文件作为脚本运行,也可以将其作为模块导入,但不能同时使用。

Directory Structure 目录结构

test/
  __init__.py
  test.py
  subwayclock/
    __init__.py
    subwayclock.py
    build/
      gen/
        __init__.py
        gtfs_realtime_pb2.py
        nyct_subway_pb2.py
      __init__.py

in this scenario test.py looks like this and works (rawFEED() is a function in subwayclock.subwayclock): 在这种情况下,test.py看起来像这样并且可以工作(rawFEED()是metroclock.subwayclock中的一个函数):

from subwayclock.subwayclock import *

print(rawFEED())

However, I cannot run the script directly ie 但是,我不能直接运行脚本,即

python subwayclock/subwayclock.py

because it gives the following error: 因为它给出以下错误:

Traceback (most recent call last):
  File "subwayclock.py", line 32, in <module>
    from .build.gen.gtfs_realtime_pb2 import FeedMessage
SystemError: Parent module '' not loaded, cannot perform relative import

HOWEVER, if I modify the import statement in subwayclock/subwayclock.py to state (ie with the leading '.' removed): 但是,如果我将metroclock / subwayclock.py中的import语句修改为状态(即删除了前导“。”):

from subwayclock.subwayclock import FeedMessage

I can run the subwayclock.py script directly through the command line, calling the main function perfectly. 我可以直接通过命令行运行metroclock.py脚本,完美调用main函数。

BUT, when I run the original test.py file, the import statement no longer works, and I get the following error: 但是,当我运行原始的test.py文件时,导入语句不再起作用,并且出现以下错误:

  Traceback (most recent call last):
  File "test.py", line 1, in <module>
        from subwayclock.subwayclock import *
      File "/var/www/test/subwayclock/subwayclock.py", line 32, in <module>
        from build.gen.gtfs_realtime_pb2 import FeedMessage
    ImportError: No module named 'build'

Can I make this script independently runnable and importable? 我可以使该脚本独立运行和导入吗?

您可以使用-m开关和标准软件包路径从软件包中运行脚本。

python -m subwayclock.subwayclock

In this case, you could just use absolute imports instead of relative imports , but depending on the dependencies between your modules, it could result in some odd behavior, where objects and classes are technically being defined twice (once in your __main__ script, and once when another module imports your module) 在这种情况下,您可以只使用绝对导入而不是相对导入 ,但是根据模块之间的依赖关系,这可能会导致某些奇怪的行为,技术上对象和类在技术上定义了两次(一次在__main__脚本中定义一次,一次当另一个模块导入您的模块时)

The proper way to do this would be to create a proper python package with a setup.py script and use the console_scripts entry point feature to expose a function as a command line script. 正确的方法是使用setup.py脚本创建适当的python包,并使用console_scripts入口点功能将函数作为命令行脚本公开。

Your project should be organized something like this. 您的项目应按以下方式组织。

/subwayclock
    /subwayclock
        __init__.py
        subwayclock.py
        ...
    setup.py

Your setup.py would look like this 您的setup.py看起来像这样

from setuptools import setup, find_packages

setup(name='subwayclock',
      version='0.1',
      packages=find_packages(),
      zip_safe=False,
      entry_points = {
          'console_scripts': ['subwayclock_script_name=subwayclock.subwayclock:rawFEED'],
      }
)

Then you just install the package 然后您只需安装软件包

$ python setup.py install

(you can also use develop mode so you can still work on it) (您也可以使用develop模式,因此仍可以进行develop

$ python setup.py develop

And you will be able to run that command line script 您将能够运行该命令行脚本

$ subwayclock_script_name

I will try to describe you, how it works and, also, to help. 我将尽力描述您的工作方式,并为您提供帮助。


Relative import 相对进口

First of all, python has a number of different methods to import some. 首先,python有多种导入方法。 Some of them is a relative import ( from .package import somemodule ) 其中一些是相对导入( from .package import somemodule
The dot means that we want to import a somemodule from the current package. 点表示我们要从当前包中导入somemodule That means that we should declare our package(when we import this module, we import it from the package , which has a name and etc.) 这意味着我们应该声明我们的包(当我们导入该模块时,我们从具有名称等的包中导入它)。


Absolute import(maybe there is another name) 绝对导入(也许有另一个名字)

This import is used nearly everywhere in simple scripts and you must know this. 在简单的脚本中,几乎在所有地方都使用此导入,您必须知道这一点。
Example: 例:

from app import db

Where app is a python module( app.py file) and db is a variable in it.If you want to know more, read the docs . 其中app是python模块( app.py文件), db是其中的变量。如果您想了解更多信息,请阅读docs



Solution

I don't really know a pretty way to avoid this, but if I were you, I would do like this: 我真的不知道一种避免这种情况的好方法,但是如果我是你,我会这样做:

if __name__ == '__main__':
    from mypackage.module import function
else:
    from .module import function

Also you can run python -m package.module.function in simple cases, but it's not quiet a good idea. 您也可以在简单的情况下运行python -m package.module.function ,但这并不是一个好主意。
Or you can add your package directory to a PYTHONPATH variable. 或者,您可以将包目录添加到PYTHONPATH变量。 See the good answer to the nearly the same question. 看到几乎相同的问题的好答案

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

相关问题 使 python3 包既可导入又可运行 - Making a python3 package both importable and runnable 如何在Sublime Text中加载任何其他软件包之前使该软件包可导入? - How can I make a package importable before any other package gets loaded in Sublime Text? 如何强制 setup.py 包含 `__init__.py` 文件并使我的 package 可导入? - How do I force setup.py to include the `__init__.py` file and make my package importable? 如何使包含文件路径的python脚本独立可执行和可导入? - How to make a python script containing file paths independently executable as well as importable? 如何使python文件相对绝对可导入? 我得到 ModuleNotFoundError 或 ImportError - How to make python file importable relatively and absolutely? I get either ModuleNotFoundError or ImportError 如何将可运行的python程序打包在1个文件中 - How to package a runnable python program in 1 file 如何使TensorFlow中的自定义Op可导入Python? - How to make custom Op in TensorFlow importable in Python? 如何在不初始化GPU的情况下使包可导入 - How to make my package importable without initializing the GPU 创建可导入的Python 3包/模块 - Creating importable Python 3 package / module 如何在python中制作文件复制脚本? - How can I make a file copying script in python?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM