- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我的第一个 Python 应用程序相当小,所有代码都在一个目录中。所有模块只是相互“导入 local_module”。在主脚本上执行“chmod +x”并运行应用程序很容易。
但现在我正在创建一个更大的命令行驱动的应用程序,我预计它会运行数万行代码。所以我想将代码分散到各个包中。此应用程序只会在工作时在内部运行。目前我们仍在使用 Python 2.6.6。看起来有几种构建事物的方法:
我通过让主脚本执行以下操作让应用程序正常工作:
import __future__ import absolute_import
然后通过以下方式调用它:
python -m main_dir.sub_dir.main_script
看来我还可以更改 Python 路径环境变量,这样我就可以调用 main_script.py,或者通过主脚本中的某些内容,例如:
sys.path.insert(0, os.path.join(THIS_DIR,'..'))
我觉得我没有足够的了解来判断什么是设置和使用多包应用程序的最佳方式。我一直在进行各种谷歌搜索,发现很多关于如何运行的引用资料,这些引用资料似乎属于上面列出的两种基本方法。但是我没有找到太多关于设置 50,000 行 Python 应用程序的信息。
更新:
凯文,谢谢你的回答。它有助于提高我对 Python 包的理解,但我仍然有点困惑。
我创建了这个目录结构:
我的应用
\子包1
\sub_package2
在所有三个目录中,我都创建了一个空的 __init__.py 文件。
在目录 my_app 中,我创建了 my_main.py :
import sys
import sub_package1.sub1
import sub_package1.sub11
import at_main_level
import at_main_level_also
def _my_print (someString):
sys.stdout.write("{0}\n".format(someString))
if __name__ == '__main__':
_my_print ("Learning about Python packages and applications.")
x = 3
doubleX = at_main_level.double_number(x)
_my_print ("Double of {0} is {1}".format(x, doubleX))
doubleDoubleX = at_main_level_also.double_double_number(x)
_my_print ("Double Double of {0} is {1}".format(x, doubleDoubleX))
xMinus1 = sub_package1.sub1.subtract_1(x)
_my_print ("{0}-1 is {1}".format(x, xMinus1))
xMinus1Twice = sub_package1.sub11.subtract1_twice(x)
_my_print ("{0}-2 is {1}".format(x, xMinus1Twice))
我还在 my_app 中创建了 at_main_level.py :
def double_number(x):
return 2 *x
最后在 my_app 中我创建了 at_main_level_also.py:
import at_main_level
def double_double_number(x):
return at_main_level.double_number(at_main_level.double_number(x))
然后在 sub_package1 中我创建了 sub1.py:
def subtract_1 (x):
return x - 1
和 sub11.py:
import sub1
def subtract1_twice(x):
return sub1.subtract_1(sub1.subtract_1(x))
现在,当我运行 my_main.py 时,我得到了对我有意义的结果:
Learning about Python packages and applications.
Double of 3 is 6
Double Double of 3 is 12
3-1 is 2
3-2 is 1
所以我可以写代码:
1) 一个模块在顶层使用另一个模块中的代码。
2) 顶层模块可以使用子包中的代码,子包中的代码可以调用子包中另一个模块中定义的函数。
但是当我在 sub_package2 中创建 sub2.py 时:
from ..sub_package1 import sub1
def subtract_2 (x):
return sub1(sub1(x))
添加到 my_main.py
import sub_package2.sub2
在我的主要功能结束时:
xMinus2 = sub_package2.sub2.subtract_2(x)
_my_print ("{0}-1 is {1}".format(x, xMinus2))
运行 my_main 时我得到以下信息:
[my_app]$ python my_main.py
Traceback (most recent call last):
File "./my_main.py", line 8, in <module>
import sub_package2.sub2
File "/home/hcate/work/temp/my_app/sub_package2/sub2.py", line 2, in <module>
from ..sub_package1 import sub1
ValueError: Attempted relative import beyond toplevel package
所以我还不明白如何创建一个应用程序,其中一个包中的代码可以使用另一个包中的代码。
我应该做什么不同的事情?
谢谢。
最佳答案
创建多个包实际上与正确地创建单个包没有区别。
永远不要混淆“您的代码所在的目录”和“Python 包的目录”。也就是说,您应该有一个目录,所有的包和模块 都在其中 — 假设它是 /users/henry/myappcode/
。 在那个目录中,可能有一些目录是用于组织代码的 Python 包;不同之处在于后者目录总是出现在导入中(当您使用绝对导入时)而前者从不出现。只要你这样做,你也不需要弄乱 sys.path
。
以下是如何使用正确的路径启动您的应用,以便导入工作:
入门的简单版本。你有这样的文件:
my_app_main.py
my_app/__init__.py
my_app/module1.py
my_app/module2.py
my_app/subpackage/...
my_app/...
您可以像这样从任何目录使用绝对或相对路径运行它:
python /users/henry/myappcode/my_app_main.py
当您使用 Python 脚本的路径调用 Python 时,Python 会自动将该脚本的位置(不是当前目录)放在sys.path
上,依此类推您所有的 .py
文件都将自动能够import my_app.module
等等。
上面的缺点是它有一个不同于模块的“主脚本”,并且与其余代码不在同一个包中。你已经知道 python -m
,所以在这种情况下让它工作的方法是:
PYTHONPATH=/users/henry/myappcode python -m my_app.main
假设您创建了 my_app/main.py
而不是上面的 my_app_main.py
。
选项 2 很丑陋。使它漂亮的方法是使您的 Python 包可安装 (setup.py
)。使用 entry_points
选项,您可以自动创建一个 shell 脚本,它执行与上述命令等效的操作,但用户只需在安装后键入 my_app
。
如果你想进行开发而不需要每次都运行 python setup.py install
,但有一个方便的命令,那么只需制作你自己的指向你的代码的 shell 脚本即可。
#!/bin/sh
PYTHONPATH=/users/henry/myappcode exec python -m my_app.main "$@"
In the directory my_app I created my_main.py with:
import sub_package1.sub1
如果您执行“python my_app/my_main.py”,那么 Python 的路径被设置为 my_app 不是包,它是一个包含顶级包的目录。这就是为什么您后来的相对导入失败并显示 relative import beyond toplevel package
的原因:您已安排 sub_package1
成为顶级包。
这里有一条一般规则:您绝不能在命令行上将包命名为目录。您可以使用 -m
(上面的选项 2 和 3)命名一个包,或者您可以调用一个不在包内的脚本(选项 1)。
您的相对导入是是正确的,但它失败了,因为 Python 没有将 my_app
视为一个包。确保您遵循选项 1(主脚本不在 my_app
内)或选项 2(主脚本使用 -m
启动)。
关于python - 如何设置多包 Python 应用程序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36011221/
通过终端,您可以使用命令 - “SetFile -a B 文件名” 以编程方式,我认为我应该通过[[NSFileManager defaultManager] createDirectoryAtPat
嗨,正在尝试书中的一些示例:Practical Graph mining with R对于子图挖掘: library(subgraphMining) library(igraph) graph1 =
代码中的相同问题: class Foo { int getIntProperty () { ... } CustomObject getObjectProperty () { ... }
所以这可能是一个愚蠢的问题,但它已经困扰我一段时间了。 使用 React,我创建了两个组件(Buttons.js 和 Message.js),每个组件都有一个导出。但是,现在我希望将这两个组件用作 n
从今天早上开始,我发现我无法再从某个范围安装任何 NPM 包(或任何具有依赖项的包)。例如,如果我输入 npm i webpack 我会收到以下错误... npm ERR! code E401 npm
我在这里搜索过,Angular 2, @ngtools/webpack, AOT ,但对我不起作用。我运行了 npm install 命令。我正在做的是创建一个新的 Angular 2 项目。当我运行
情况: 我有一个 Swift 包,将其命名为 lib。 lib 位于其自己的存储库中。在lib的仓库中,有一堆本地包;也就是说,这些包是在 lib 中定义的,使用本地路径依赖格式 .package(p
我想在工作中学习和使用nodejs,但是在使用 de npm 命令安装模块/包时遇到网络问题。我是否可以使用我的家用计算机构建完整的 Node js 包,然后将其安装在另一台计算机(我的工作场所计算机
我需要将一些 .tar.bz2 格式的非 Python 包转换为 Anaconda/miniConda .egg 文件并安装它们。为此,我需要一个适用于 Windows 的 bld.bat 文件。互联
我需要共享库文件 libthrift-0.9.3.so 作为其他包的依赖项。我在构建 thrift-0.9.3 包时看到编译问题(我确实从 https://thrift.apache.org/down
我尝试在 R 版本 3.5.0 中安装“arcgisbinding”包。但是我失败了,得到以下错误和警告。 Installing package into ‘C:/Users/Lenovo/Docum
我尝试在 R 版本 3.5.0 中安装“arcgisbinding”包。但是我失败了,得到以下错误和警告。 Installing package into ‘C:/Users/Lenovo/Docum
我试图在 flutter 中测试这个应用程序,但我无法运行该应用程序,因为出现此错误“名称‘Page’在库‘package:burn_off/widgets/page.dart’和‘package’中
试图理解和学习如何编写包...用我一直使用的东西进行测试,记录... 您能帮我理解为什么“日志”变量不起作用...并且屏幕上没有日志记录吗? 谢谢! 主要文件: #!/opt/local/bin/py
我尝试运行此使用 Google 云的代码。 import signal import sys from google.cloud import language, exceptions # creat
我想知道是否有人找到了一个很好的 R 包来分析眼动追踪数据? 我遇到了 eyetrackR,但据我所知,没有可用的英文支持文档: http://read.psych.uni-potsdam.de/pm
我正在 R 上制作一个包。我有两个函数共享一个变量(全局)。 如何将其导入到包中? 例如, m<-0 f<-function() { m <- m+1 } g<-function() { m <- m
我用 C 为 Lua 编写了很多模块。每个模块都包含一个 Lua 用户数据类型,我像这样加载和使用它们: A = require("A") B = require("B") a = A.new(3,{
我正在尝试在 R 中的 Ubuntu 上安装 xlsx 包,以便使用允许在 R 中插入链接然后将它们导出到 Excel 的功能。 话虽如此,我根本无法安装该软件包。 显然它必须与 rJava 一起使用
我想在 Haskell 中做一些蒙特卡洛分析。我希望能够编写这样的代码: do n <- poisson lambda xs <- replicateM n $ normal mu sigma
我是一名优秀的程序员,十分优秀!