21

Let's assume I have a python package called bestpackage.

Convention dictates that bestpacakge would also be a directory on sys.path that contains an __init__.py to make the interpreter assume it can be imported from.

Is there any way I can set a variable for the package name so the directory could be named something different than the directive I import it with? Is there any way to make the namespacing not care about the directory name and honor some other config instead?

My super trendy client-side devs are just so much in love with these sexy something.otherthing.js project names for one of our smaller side projects!

EDIT:

To clarify, the main purpose of my question was to allow my client side guys continue to call the directories in their "projects" (the one we all have added to our paths) folder using their existing convention (some.app.js), even though in some cases they are in fact python packages that will be on the path and sourced to import statements internally. I realize this is in practice a pretty horrible thing and so I ask more out of curiosity. So part of the big problem here is circumventing the fact that the . in the directory name (and thereby the assumed package name) implies attribute access. It doesn't really surprise me that this cannot be worked around, I was just curious if it was possible deeper in the "magic" behind import.

There's some great responses here, but all rely on doing a classical import of some kind where the attribute accessor . will clash with the directory names.

DeaconDesperado
  • 8,971
  • 6
  • 43
  • 75

5 Answers5

15

A directory with a __init__.py file is called a package.

And no, the package name is always the same as the directory. That's how Python can discover packages, it matches it against directory names found on the search path, and if there is a __init__.py file in that directory it has found a match and imports the __init__.py file contained.

You can always import something into your local module namespace under a shorter, easier to use name using the from module import something or the import module as alias syntax:

from something.otherthing.js import foo
from something.otherthing import js as bar
import something.otherthing.js as hamspam
Martijn Pieters
  • 889,049
  • 245
  • 3,507
  • 2,997
  • On a side note, one can always do `import X as Y`. So you *must* call the directory "X" but you can refer to it as "Y" in the code.(Maybe that's enough for the OP?) – Bakuriu Nov 06 '12 at 17:23
  • @Bakuriu: yeah, on second reading (edited?) that's probably what the OP wants anyway. Updated. – Martijn Pieters Nov 06 '12 at 17:26
  • Perhaps I wasn't clear about this.. the main problem here is synchronizing a bunch of locally running flask apps that are packages. The system is a client side api that has a server-side backend in flask, so my client devs all named their dirs something to the effect of 'the.project.js' since that's the typical thing they do with their projects. This of course is a big problem for th e python interpreter when treating these as packages. – DeaconDesperado Nov 06 '12 at 20:03
5

There is one solution wich needs one initial import somewhere

>>> import sys
>>> sys.modules['blinot_existing_blubb'] = sys
>>> import blinot_existing_blubb
>>> blinot_existing_blubb
<module 'sys' (built-in)>

Without a change to the import mechanism you can not import from an other name. This is intended, I think, to make Python easier to understand.

However if you want to change the import mechanism I recommend this: Getting the Most Out of Python Imports

User
  • 12,769
  • 1
  • 32
  • 55
1

Well, first I would say that Python is not Java/Javascript/C/C++/Cobol/YourFavoriteLanguageThatIsntPython. Of course, in the real world, some of us have to answer to bosses who disagree. So if all you want is some indirection, use smoke and mirrors, as long as they don't pay too much attention to what's under the hood. Write your module the Python way, then provide an API on the side in the dot-heavy style that your coworkers want. Ex:

pythonic_module.py

def func_1():
    pass

def func_2():
    pass

def func_3():
    pass

def func_4():
    pass

indirection

/dotty_api_1/__init__.py

from pythonic_module import func_1 as foo, func_2 as bar

/dotty_api_2/__init__.py

from pythonic_module import func_3 as foo, func_4 as bar

Now they can dot to their hearts' content, but you can write things the Pythonic way under the hood.

Silas Ray
  • 24,298
  • 5
  • 44
  • 60
1

Actually yes! you could do a canonical import Whatever or newmodulename = __import__("Whatever")

python keeps track of your modules and you can inspect that by doing:

import sys
print sys.modules

See this article more details

But that's maybe not your problem? let's guess: you have a module in a different path, which your current project can't access because it's not in the sys-path?

well the just add:

import sys
sys.path.append('path_to_the_other_package_or_module_directory')

prior to your import statement or see this SO-post for a more permanent solution.

Community
  • 1
  • 1
Don Question
  • 10,018
  • 4
  • 32
  • 50
1

I was looking for this to happen with setup.py at sdist and install time, rather than runtime, and found the directive package_dir:

Gringo Suave
  • 25,443
  • 6
  • 77
  • 69