views:

74

answers:

1

I have a py file like this, which errors out.

from world import acme

def make_stuff_happen():
    acme.account.foo()       # Works
    acme.subscription.bar()  # FAIL: "module 'object' has no attribute 'subscription'"

make_stuff_happen()

But this works!

from world import acme 
from world.acme import subscription

def make_stuff_happen():
    acme.account.foo()  # Works
    subscription.bar()  # Now this works.

make_stuff_happen()

All I can say is WTF, What could be causing this? The behavior should at least be consistent for both acme.account and acme.subscription.

Thanks!

Update- Folder structure of the acme folder:

acme
|-- __init__.py
|-- account.py
|-- catalog.py
|-- core.py
|-- proxy.py
|-- subscription.py
`-- utils.py

And __init__.py is completely blank.

+6  A: 

Submodules are referenced in the __init__.py file in the module folder. It appears that subscription is not referenced in acme's __init__.py.

However, when you do import world.acme.subscription, it knows to go digging in that folder without talking to __init__.py.

According to your description of __init__.py as being empty, you should import subscription in __init__.py.

More on how modules are set up can be seen in the documentation. There is a pretty good example setting up a sound module.

orangeoctopus
That would make sense, but in this case the `acme/__init__.py` file is blank
Infinity
That is the problem. In `__init__.py` you should "include subscription"
orangeoctopus
Precisely - since your `__init__.py` is blank, it doesn't reference subscription, which means you need to directly import it.
Wayne Werner
This makes sense I guess, but why does acme.account work then?Both `acme/subscription.py` and `acme/account.py` have the same structure: regular files with a few functions in it
Infinity
Yes, and if you don't have the ability to change `__init__.py` you have no other choice than to import it directly.
orangeoctopus
I agree that `account` working is strange, I didn't notice that before. Perhaps it is being included in `world`, or something like that.
orangeoctopus
Ehm, this is not really how it works. The problem is that *modules do not get imported unless you import them*. `acme.subscription` won't be available unless something imports it -- something anywhere in your program. After anything in your program imports `acme.subscription`, *any* code that imports (or has imported) `acme` will see `acme.subscription`. The answer is simply to import what you use, and not rely on something else importing submodules.
Thomas Wouters
@Thomas thanks, that explains what's happening. Is there a good way to to allow what I'm trying to do? I would like be able to just do `from world import acme` and be able to use anything in `acme`, without any more importing.
Infinity
Then you will have to have `acme/__init__.py` import all modules under it. Keep in mind that that means all those modules will always be imported as soon as you import `acme` though.
Thomas Wouters