python: Two modules and classes with the same name

2020-02-07 18:59发布

问题:

I have started to learn python and writing a practice app. The directory structure looks like

src
 |
 --ShutterDeck
    |
    --Helper
       |
       --User.py -> class User
    --Controller
       |
       --User.py -> class User

The src directory is in PYTHONPATH. In a different file, lets say main.py, I want to access both User classes. How can I do it.

I tried using the following but it fails:

import cherrypy
from ShutterDeck.Controller import User
from ShutterDeck.Helper import User

class Root:
  @cherrypy.expose
  def index(self):
    return 'Hello World'

u1=User.User()
u2=User.User()

That's certainly ambiguous. The other (c++ way of doing it) way that I can think of is

import cherrypy
from ShutterDeck import Controller
from ShutterDeck import Helper

class Root:

  @cherrypy.expose
  def index(self):
    return 'Hello World'

u1=Controller.User.User()
u2=Helper.User.User()

But when above script is run, it gives the following error

u1=Controller.User.User()
AttributeError: 'module' object has no attribute 'User'

I'm not able to figure out why is it erroring out? The directories ShutterDeck, Helper and Controller have __init__.py in them.

回答1:

You want to import the User modules in the package __init__.py files to make them available as attributes.

So in both Helper/__init_.py and Controller/__init__.py add:

from . import User

This makes the module an attribute of the package and you can now refer to it as such.

Alternatively, you'd have to import the modules themselves in full:

import ShutterDeck.Controller.User
import ShutterDeck.Helper.User

u1=ShutterDeck.Controller.User.User()
u2=ShutterDeck.Helper.User.User()

so refer to them with their full names.

Another option is to rename the imported name with as:

from ShutterDeck.Controller import User as ControllerUser
from ShutterDeck.Helper import User as HelperUser

u1 = ControllerUser.User()
u2 = HelperUser.User()


回答2:

One way is just:

import ShutterDeck.Controller.User
import ShutterDeck.Helper.User

cuser = ShutterDeck.Controller.User.User()
huser = ShutterDeck.Helper.User.User()

You can also do this:

from ShutterDeck.Controller.User import User as ControllerUser
from ShutterDeck.Helper.User import User as HelperUser


回答3:

This might also help (struggled with similar problem today):

ShutterDeck
├── Controller
│   ├── __init__.py
│   └── User.py
├── Helper
│   ├── __init__.py
│   └── User.py
└── __init__.py

in ShutterDeck/{Controller,Helper}/__init__.py:

from .User import User

And then:

>>> import ShutterDeck.Helper
>>> helperUser = ShutterDeck.Helper.User()
>>> helperUser
<ShutterDeck.Helper.User.User object at 0x1669b90>
>>> import ShutterDeck.Controller
>>> controllerUser = ShutterDeck.Controller.User()
>>> controllerUser
<ShutterDeck.Controller.User.User object at 0x1669c90>