13

Please consider the following Python modules excerpts:

foo.py:

class Foo:
  (...)

bar.py:

import foo

foo = foo.Foo()

The variable foo, which was a module object, is overwritten with a Foo object.

I know that I can use other names for the object, e.g.:

foobar = foo.Foo()

but semantically it makes more sense in my code to have it called foo, since it will be the only instance.

(I tried to workaround this by dropping classes and using modules only, but I went back to using classes because using modules only had "robustness" problems.)

This is kind of a philosophical question, but what is the "right" way of handling this potential object/module names clash?

João M. S. Silva
  • 1,078
  • 2
  • 11
  • 24
  • I don't think there is one right way for all modules -- it really depends on the module name. As @F.J points out, you could import it as something different, but I'd sooner change my variable name. What are the module and class names in your specific case? – Ben Hoyt Apr 03 '13 at 23:17
  • The module/class names are camera, network, gpio, database, etc. – João M. S. Silva Apr 04 '13 at 00:43
  • Yeah, I can see how you'd want to name a `camera.Camera()` instance `camera`. Perhaps just import the class names and not the whole modules, as in `from camera import Camera`? Then you can safely use `camera` as your variable name. – Ben Hoyt Apr 04 '13 at 01:33
  • Thanks, that's an interesting alternative. I haven't considered it before since I always import full modules. I tend to consider partial imports "dangerous" or less robust. But in this particular case it may be an elegant solution. – João M. S. Silva Apr 05 '13 at 03:50

3 Answers3

9

In my opinion there is nothing wrong with what you are currently doing, but to make it more clear for everyone reading the code I would suggest changing your code to something like the following:

import foo as foo_mod

foo = foo_mod.Foo()

Or alternatively:

from foo import Foo

foo = Foo()

This prevents the name clash so it will be more obvious that the variable foo in your module is not going to refer to the module of the same name.

Andrew Clark
  • 202,379
  • 35
  • 273
  • 306
0

I've also been favoring the following style nowadays:

import foo

my_foo = foo.Foo()

I prefer this because it keeps module names untouched, and those are are more global and sacred than local variables.

Ciro Santilli OurBigBook.com
  • 347,512
  • 102
  • 1,199
  • 985
0

This pattern doesn't seem to bother peeps who use Flask + Celery,

from celery import Celery

def make_celery(app):
    celery = Celery(
        app.import_name,
        backend=app.config['CELERY_RESULT_BACKEND'],
        broker=app.config['CELERY_BROKER_URL']
    )
    ...

Obviously, the correct way to create an instance of this class is stalk = Celery() (hehe)

xtian
  • 2,765
  • 7
  • 38
  • 65