1

Lets assume the following structure of directories for a project

<root>
  __init__.py
  helloworld.py
<moduleOne>
  f.txt
  __init__.py
  printfile.py

where root and moduleOne are directories

Content of helloworld.py:

#!/usr/bin/python
import helloworld.printfile
printf()

Content of moduleOne/printfile

#!/usr/bin/python
f = open('f.txt')

def printf():
    print 'print file'
    print f

if __name__ == '__main__':
   printf()

My issue:

From moduleOne/ the execution of printfile is ok, but from root/, if i run helloworld.py the following error happens:

import moduleOne.printfile
File "/root/moduleOne/printfile.py", line 5, in <module>
 f = open('f.txt')
IOError: [Errno 2] No such file or directory: 'f.txt'

How to solve this in python?

[Edited]

I solved (more or less) this issue with a "workaround", but stil have a problem:

My solution:

In moduleOne/printfile

import sys
fname = 'moduloOne/f.txt'

def printf():

    f = open(fname)
    print 'print file'  
    print f

if __name__ == '__main__':

    fname = 'f.txt'
    printf()    

But....

lets say i have a new directory, from the root, called etc, then the new structure is:

<root>
  __init__.py
  helloworld.py
<moduleOne>
  f.txt
  __init__.py
  printfile.py
<etc>
  f2.txt

And now i need to acess etc/f2.txt from moduleOne/printfile. how?

Sidon
  • 1,316
  • 2
  • 11
  • 26
  • Have you tried f = open('moduleOne/f.txt')? –  May 08 '14 at 12:02
  • I tried this (now), works from but fail from : IOError: [Errno 2] No such file or directory: 'moduleOne/f.txt' – Sidon May 08 '14 at 13:37
  • Do you need to access 'f.txt' from both modules? –  May 08 '14 at 14:35
  • Yes, actualy i need acess f.txt (a configuration file) from others modules. – Sidon May 08 '14 at 15:15
  • Is 'f.txt' in root or moduleOne? –  May 08 '14 at 16:01
  • No matter, but i need access to f.txt in all modules, for example: root/module1/submodul1. I need acess to f.txt on all three modules. – Sidon May 08 '14 at 16:37
  • You might need to put the full system link to the file then instead of 'f.txt' put the full path to the file. –  May 08 '14 at 17:36
  • I can't do it, the program will run on more of the one environment (different). – Sidon May 08 '14 at 17:45
  • Have you listed the contents of helloworld.py correctly? Should it be 'import moduleOne.printfile'? –  May 08 '14 at 18:05

1 Answers1

1

You need more abstraction.

  1. Don't hard-code the file path in printfile.py
  2. Don't access a global in the printf function.
  3. Do accept a file handle as a parameter to the printf function:

    def printf(file_handle):
        print 'print file'
        print file_handle
    
  4. In a script that does actually need to know the path of f.txt (I guess helloworld.py in your case), put it there, open it, and pass it to printf:

    from moduleOne.printfile import printf
    
    my_f_file = open('/path/to/f.txt')
    printf(my_f_file)
    
  5. Better yet, get the file path from the command line

    import sys
    
    from moduleOne.printfile import printf
    
    input_file_path = sys.argv[1]
    my_f_file = open(input_file_path)
    printf(my_f_file)
    

EDIT: You said on your Google+ cross-post:

full path is problem, the program will run on differents environments.

If you're trying to distribute your program to other users and machines, you should look into making a distribution package (see side note 3 below), and using package_data to include your configuration file, and pkgutil or pkg_resources to access the configuration file. See How do I use data in package_data from source code?

Some side-notes:

  1. Represent directories as the directory name with a trailing slash, à la the conventions of the tree command: / instead of <root>, moduleOne/ instead of <moduleOne>
  2. You're conflating "module" with "package". I suggest you rename moduleOne/ to packageOne/. A directory with an __init__.py file constitutes a package. A file ending in a .py extension is a module. Modules can be part of packages by physically existing inside a directory with an __init__.py file. Packages can be part of other packages by being a physical subdirectory of a parent directory with an __init__.py file.
  3. Unfortunately, the term "package" is overloaded in Python and also can mean a collection of Python code for distribution and installation. See the Python Packaging Guide glossary.
Community
  • 1
  • 1
gotgenes
  • 38,661
  • 28
  • 100
  • 128