I know that certain functions will check the script's or module's current directory for the file if no path is specified.

open('test.txt')

If that script is run and test.txt is in the same directory that will open the correct file.

However, if I try to import that module it doesn't work because presumably the path is different. How can I get this to work proper?

import sys,os
sys.path.append(os.path.curdir)

Doesn't work. Here's an example of what I'm trying to do.

My script that I'm running from the desktop.

#import module from package in site-packages.
from mypackage import mymodule

print(mymodule.variable)

My module.

import configparser

myconfig = configparser.ConfigParser()

#Read in the configuration file in the same directory as the module.
myconfig.read('mycfg.cfg')

myvariable = myconfig.get('MYSECTION', 'MYVARIABLE', 0)

The configuration file.

[MYSECTION]
MYVARIABLE=55

Running the desktop script produces this error, like the configuration file isn't even there.

Traceback (most recent call last):
  File "C:\Documents and Settings\User\Desktop\myscript.py", line 2, in <module>
    from mypackage import mymodule
  File "C:\Python31\lib\site-packages\mypackage\mymodule.py", line 8, in <module>
    myvariable = myconfig.get('MYSECTION', 'MYVARIABLE', 0)
  File "C:\Python31\lib\configparser.py", line 537, in get
    raise NoSectionError(section)
configparser.NoSectionError: No section: 'MYSECTION'

Moving the configuration file to the desktop remedies this, but I don't want to have to keep the module configuration file where any script that uses the module is at. I want the module to refer to the configuration file in its directory.

Move module to same directory as main script or configuration file to same directory as modules or say subdirectory config.

Put your code better place than Desktop and put that to path.

commented: Not the correct answer. +0

It might just be the space-in-directory-name problem the some versions of Windows have.
Try the well known kludge ...

# the Microsoft kludge, quoting a string within a string fixes the 
# space-in-folder-name problem, tells the OS to use the whole string
# including spaces as a single command
'"C:/Documents and Settings/User/Desktop/myscript.py"'
commented: A legitimate attempt to help the user accomplish what they want to accomplish. +1

I'm not using a directory name with spaces in it.

That was just the error message.

You could be right, vegaseat, I have enough experience of these '"C:\Program" does not exist' style errors. As personal aside I can say that I can live with this, but why or why the Windows does not then accept quotation marks in path variable? ARRRGH!

The answer is to develop good habits, one of which is to always use the complete path. It makes everything obvious. This also helps when you come back years later to debug a program because someone has moved something.

commented: Answer is not correct. +0

Sometimes specifying a path or package relative to the current module is the best way to do it, especially when the path or package referred to can change location.

Say you have a package and you create a submodule with several dependencies to other submodules in the same package. You explicitly import each module from the package.

from mypackage import module1
from mypackage import module2
from mypackage import module3

Works fine. No complaints. However, later your package becomes a subpackage for another package. So you have to edit the file.

from mypackage.mysubpackage import module1
from mypackage.mysubpackage import module2
from mypackage.mysubpackage import module3

Not good. The more dependencies or the larger the change in nesting the worse editing is. Even if you didn't mind your users might. That's why you use relative imports.

#'.' represents the module's package.
from . import module1
from . import module2
from . import module3

That will always work no matter if the package is the highest package or it is turned into a subpackage. No editing required.

It's not too much to ask for relative paths.

And I figured out a way to do it no thanks to you guys. :D

I thought I was asking for an arm, a leg, a firstborn child, and a million dollars the way you guys were holding out on assistance.

The script on the desktop.

from mypackage import mymodule

print(mymodule.MYVARIABLE)

The module.

import configparser
import os
import sys

config = configparser.ConfigParser()

#If the module is executed as a script __name__ will be '__main__' and sys.argv[0] will be the full path of the module.
if __name__ == '__main__':
    path = os.path.split(sys.argv[0])[0]
#Else the module was imported and it has a __file__ attribute that will be the full path of the module.
else:
    path = os.path.split(__file__)[0]

#The configuration parser reads the file at the full path made by joining the base path and the file name.
config.read(os.path.join(path, 'mycfg.cfg'))

MYVARIABLE = config.get('MYSECTION', 'MYVARIABLE', 0)

The configuration file in the same directory as the module.

[MYSECTION]
MYVARIABLE=55
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.