im_infamous
im_infamous

Reputation: 327

python __main__ and __init__ proper usage

Since I'm rather new to python this particular aspect of language still opaque for me.

So, assume that my project contains many files with code that does stuff and two "service" files: __init__.py and __main__.py

In __init__.py there is only:

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

And in __main__.py as follows:

import package # ok
import package2 # ok

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

So my question is: why both packages are visible while functions inside are not? I've read some source code from google and still can't spot the difference between it and my code. I'm using Python 3.5.1

I assume, that code in __init__ will launch __main__ and __main__ will launch the rest of my functions.

UPD

Well, my apologies if I confused someone with my code. The idea that stand behind __init__.py is that file was created by IDE when the first package was added so I decided to fill it with code found on first github entry(my fault, I though it can be re-used by copy-paste).

Strictly speaking I just need python construction, that equivalent this C code:

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

And the following code

import package
import package2 

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

has exactly same issue that stated above, so the matter is not in __init__.py

Upvotes: 12

Views: 34822

Answers (3)

hpaulj
hpaulj

Reputation: 231375

I made:

foo/
  __init__.py
  __main__.py

with the 2 files being:

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

and

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

If I run __main__ directly:

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

It does same thing if I invoke the directory. It does not import __init__.py.

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

But from a shell, it loads both files

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

But it does not use the if __name__ block of __main__ - the name isn't right, it's now foo.__main__.


relevant docs

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

Execute the Python code contained in script, which must be a filesystem path (absolute or relative) referring to either a Python file, a directory containing a __main__.py file, or a zipfile containing a __main__.py file.

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

This module represents the (otherwise anonymous) scope in which the interpreter’s main program executes — commands read either from standard input, from a script file, or from an interactive prompt. It is this environment in which the idiomatic “conditional script” stanza causes a script to run:


I created another directory with an __init__.py but no main:

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

import works, but I can't run the directory.

Upvotes: 6

im_infamous
im_infamous

Reputation: 327

So, as stated in question for such C code

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

there is some kind of python solution:

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

as follows __main__.py:

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


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

if __name__ == "__main__":
    main()

No __init__.py required. In my case assumed that all files are located in same directory.

Any corrections are welcome.

Upvotes: 0

Clodion
Clodion

Reputation: 1017

Well:

__init__.py Is useful for import (all subdirectories are search for import)

And

if __name__ == "__main__":

is use to run a module itself. But this par of code would not be executed if imported in other script

Upvotes: 2

Related Questions