【问题标题】:python __main__ and __init__ proper usagepython __main__ 和 __init__ 正确使用
【发布时间】:2016-05-17 11:35:15
【问题描述】:

由于我对 python 比较陌生,所以语言的这个特定方面对我来说仍然是不透明的。

因此,假设我的项目包含许多文件和两个“服务”文件:__init__.py__main__.py

__init__.py 中只有:

if __name__ == "__main__":
    import package.__main__
    __main__.main()

__main__.py中如下:

import package # ok
import package2 # ok

def main():
    package.myfunc1() # can't find reference to myfunc1
    package2.myfunc2() # can't find reference to myfunc2

所以我的问题是:为什么两个包都是可见的,而里面的函数不可见?我从谷歌阅读了一些源代码,但仍然无法发现它与我的代码之间的区别。我正在使用Python 3.5.1

我认为,__init__ 中的代码将启动 __main____main__ 将启动我的其余功能。

UPD

好吧,如果我把我的代码弄糊涂了,我深表歉意。 __init__.py 背后的想法是该文件是在添加第一个包时由 IDE 创建的,所以我决定用在第一个 github 条目上找到的 code 填充它(我的错,我虽然可以通过复制重新使用它-粘贴)。

严格来说我只需要python构造,相当于这个C代码:

header.h
void func1(){...} //in code1.c
void func2(){...} //in code2.c
#include "header.h"
int main() //in main.c 
{
    func1();
    func2();
    return 0;
}

还有下面的代码

import package
import package2 

if __name__ == "__main__":
    package.myfunc1() 
    package2.myfunc2() 

和上面说的有完全相同的问题,所以问题不在__init__.py

【问题讨论】:

  • 如果你不知道自己在做什么,就不要在__init__.py里放代码,你只会徒劳地迷惑自己,一无所获。 (如果您确实知道自己在做什么,请同情下一位读者,不要在没有令人信服的理由和证明其合理性的情况下将代码放入 __init__.py。)
  • __init__.py 在包结构中有一个定义的位置。我不认为__main__.py 会。运行脚本时,__main__ 是基本命名空间的名称,因此是 if __name__ ... 成语。 __main__的两种用法不一样。
  • @hpaulj:在 Python 3.1+ 中,如果一个目录或 zipfile 有一个__main__.py 文件,您可以通过指定目录/zipfile 的路径来运行它。
  • 是的,这就是我在回答中发现的。

标签: python initialization main


【解决方案1】:

嗯:

__init__.pyimport有用(所有子目录都搜索导入)

还有

if __name__ == "__main__":

用于运行模块本身。但是这一段代码如果导入其他脚本是不会被执行的

【讨论】:

  • 问题是关于文件__main__.py,而不是模块名称__main__
  • @chepner:没有。在__init__.py 中,if __name__ == "__main__": 是第一条语句。这就是在这个模块中调用main 函数。但可以肯定的是,可能会添加一些解释!
【解决方案2】:

我做了:

foo/
  __init__.py
  __main__.py

这两个文件是:

# __init__.py
import __main__
print('in init')
print('init name',__name__)

# __main__.py
print('main name',__name__)
print('in main')    
if __name__=='__main__':
    print('in main main block')

如果我直接运行__main__

1538:~/mypy$ python foo/__main__.py
('main name', '__main__')
in main
in main main block

如果我调用目录,它会做同样的事情。它不会导入__init__.py

1541:~/mypy$ python foo
('main name', '__main__')
in main
in main main block

但从 shell 中,它会加载两个文件

1542:~/mypy$ python
....
>>> import foo
('main name', 'foo.__main__')
in main
in init
('init name', 'foo')

但它没有使用 __main__if __name__ 块 - 名称不对,现在是 foo.__main__


相关文档

https://docs.python.org/2/using/cmdline.html#interface-options

执行脚本中包含的 Python 代码,该代码必须是一个文件系统路径(绝对或相对),它引用 Python 文件、包含 __main__.py 文件的目录或包含 __main__.py 文件的 zip 文件。

https://docs.python.org/2/library/\__main__.html

这个模块代表解释器的主程序执行的(或者匿名的)范围——从标准输入、脚本文件或交互式提示中读取的命令。正是在这种环境中,惯用的“条件脚本”节导致脚本运行:


我用__init__.py 创建了另一个目录,但没有主目录:

1558:~/mypy$ python foo1
/usr/bin/python: can't find '__main__' module in 'foo1'
1558:~/mypy$ python
...
>>> import foo1
('in init', 'foo1')
>>> 

import 有效,但我不能run 目录。

【讨论】:

  • 感谢您的提示,它帮助我弄清楚了几件事,最终找到了解决问题的方法。不幸的是,一旦没有适合我目的的直接代码,就无法接受您的回答
【解决方案3】:

因此,正如针对此类 C 代码所讨论的那样

header.h
void func1(){...} //in code1.c
void func2(){...} //in code2.c
#include "header.h"
int main() //in main.c 
{
    func1();
    func2();
    return 0;
}

有某种python解决方案:

def func1() #  in function1.py in package Foopackage
def func2() #  in function2.py in package Foopackage

如下__main__.py:

import Foopackage.function1 as f1
import Foopackage.function2 as f2


def main():
    f1.func1()
    f2.func2()

if __name__ == "__main__":
    main()

不需要__init__.py。在我的情况下,假设所有文件都位于同一目录中。

欢迎指正。

【讨论】:

    猜你喜欢
    • 2020-03-13
    • 1970-01-01
    • 2015-09-28
    • 1970-01-01
    • 2022-08-17
    • 1970-01-01
    • 2011-06-14
    • 2013-09-03
    • 2014-09-11
    相关资源
    最近更新 更多