1

我以这种方式使用 distutils 在 python 中制作了一个包:

#! /usr/bin/env python

from distutils.core import setup

setup(name='mypackage4.py',
    version='1.0',
    description='Description',
packages=['mypackage4']
)

setup.py 然后将它安装到我的 python2.7/site-packages 目录。

当我跑

import mypackage4

它尝试运行 mypackage4 目录中的 .py 文件。该目录包含包含函数(def 命令)的 python 文件。我要做的就是使这些功能可供使用,而不是直接在导入时运行。

但是,如果我这样做

cd python2.7/site-packages

然后进行导入,以便它在本地获取 mypackage4,它在不运行任何东西的情况下导入,所以我可以以正常方式从 python 命令行访问这些函数。

为什么python似乎在包不在本地目录时运行函数,但在包在本地目录时不运行函数?

其次,我读到了关于放置一个

if __name__ == '__main__':
    pass
else:
    <define functions here>

我的 .py 文件中的命令以防止它们运行,但是它肯定不会运行这些函数,那么它是如何知道它们的呢?

任何帮助是极大的赞赏!

ps,(以防万一)在我的包目录中,我有一个__init__.py文件告诉python要导入哪些文件

__all__ = [
    'pyfile1',
    'pyfile2',
    'pyfile3',
]
4

1 回答 1

3

该目录包含包含函数(def 命令)的 python 文件。我要做的就是使这些功能可供使用,而不是直接在导入时运行。

语句是必须运行的def代码,或者没有定义函数。当你导入一个模块或包时,Python总是运行你的代码。函数、类和全局变量/常量定义是代码,就像其他任何东西一样。

除非您编写代码来调用它们,否则不会调用这些函数。但是,如果您确实编写了这样的代码,它就会运行。没有特殊状态def foo(i): print(i)发生,但foo(3)没有;您的所有代码都会运行。

有时,您想编写一个可以由其他代码导入但也可以作为脚本运行的模块。(或者您可能只希望模块在作为脚本执行时运行其测试。)这就是__main__成语的用武之地。

你的习语有点错误——或者,更确切地说,你把一个不常见的情况放在典型的前面。通常,您会执行以下操作:

def foo(f):
    blahblah(f)

def bar(fname):
    with open(fname) as f:
        foo(f)

if __name__ == '__main__':
    import sys
    for arg in sys.argv[1:]:
        bar(arg)

当您导入模块时,fooandbar定义会被执行,因此导入代码可以执行qux.bar(fname),但if语句中的内容不会被执行(因为__name__ != '__main__'对于导入的模块)。当您将模块作为脚本运行时,这些东西确实会被执行(因为__name__ == '__main__')。所以,你可以做./qux.py myfile.txt(​​或C:\Python33\Python.exe .\qux.py myfile.txt,或其他),它会为你解决 myfile.txt 的问题。

你很少需要elseif __name__ == '__main__'.

但很少不是从来没有。有时,您有将模块用作模块所需的定义,但不需要将其作为脚本运行。如果编译这些定义需要很长时间(例如,因为模块预先计算了 100000 个元素dict以加速以后的访问),那么您不希望每次运行脚本时都这样做。因此,这些定义将进入该else块。

于 2013-01-07T07:35:06.943 回答