Python:类名与文件/模块名相同导致继承问题?

Posted

技术标签:

【中文标题】Python:类名与文件/模块名相同导致继承问题?【英文标题】:Python: Classname same as file/module name leads to inheritance issue? 【发布时间】:2011-01-24 12:18:02 【问题描述】:

我的代码在一个文件中运行良好。现在,我将类分成不同的模块。模块已被赋予与类相同的名称。也许这是一个问题,因为MainPage 在加载时失败。它是否认为我正在尝试从模块继承?模块/类命名空间冲突会发生吗?

MainPage.py

import BaseHandler
from models import Item
from Utils import render

class MainPage(BaseHandler):
    def body(self, CSIN=None): #@UnusedVariable
        self.header('Store')
        items = Item.all().order('name').fetch(10)
        render('Views/table.html', self, 'items': items)
        self.footer()

BaseHandler.py

from google.appengine.ext import webapp
from google.appengine.api import users
from Utils import *

# Controller
class BaseHandler(webapp.RequestHandler):
     # ... continues ... 

故障回溯:

Traceback (most recent call last):
  File "C:\Program Files\Google\google_appengine\google\appengine\tools\dev_appserver.py", line 3180, in _HandleRequest
    self._Dispatch(dispatcher, self.rfile, outfile, env_dict)
  File "C:\Program Files\Google\google_appengine\google\appengine\tools\dev_appserver.py", line 3123, in _Dispatch
    base_env_dict=env_dict)
  File "C:\Program Files\Google\google_appengine\google\appengine\tools\dev_appserver.py", line 515, in Dispatch
    base_env_dict=base_env_dict)
  File "C:\Program Files\Google\google_appengine\google\appengine\tools\dev_appserver.py", line 2382, in Dispatch
    self._module_dict)
  File "C:\Program Files\Google\google_appengine\google\appengine\tools\dev_appserver.py", line 2292, in ExecuteCGI
    reset_modules = exec_script(handler_path, cgi_path, hook)
  File "C:\Program Files\Google\google_appengine\google\appengine\tools\dev_appserver.py", line 2188, in ExecuteOrImportScript
    exec module_code in script_module.__dict__
  File "C:\Users\odp\workspace\Store\src\Main.py", line 5, in <module>
    import MainPage
  File "C:\Program Files\Google\google_appengine\google\appengine\tools\dev_appserver.py", line 1267, in Decorate
    return func(self, *args, **kwargs)
  File "C:\Program Files\Google\google_appengine\google\appengine\tools\dev_appserver.py", line 1917, in load_module
    return self.FindAndLoadModule(submodule, fullname, search_path)
  File "C:\Program Files\Google\google_appengine\google\appengine\tools\dev_appserver.py", line 1267, in Decorate
    return func(self, *args, **kwargs)
  File "C:\Program Files\Google\google_appengine\google\appengine\tools\dev_appserver.py", line 1819, in FindAndLoadModule
    description)
  File "C:\Program Files\Google\google_appengine\google\appengine\tools\dev_appserver.py", line 1267, in Decorate
    return func(self, *args, **kwargs)
  File "C:\Program Files\Google\google_appengine\google\appengine\tools\dev_appserver.py", line 1770, in LoadModuleRestricted
    description)
  File "C:\Users\odp\workspace\Store\src\MainPage.py", line 10, in <module>
    class MainPage(BaseHandler):
TypeError: Error when calling the metaclass bases
    module.__init__() takes at most 2 arguments (3 given)

更新我似乎已经解决了。这种导入效果更好:

from BaseHandler import BaseHandler

模块和类名相同是不是很糟糕?

【问题讨论】:

只要大小写不同,模块名和类名相同就不错了。在 Python 中,约定模块名全部小写,类名使用 CamelCase。我建议你阅读 Python 风格指南 (PEP 8) - python.org/dev/peps/pep-0008。非常有帮助! 【参考方案1】:

是的,模块名称与其他所有模块名称共享相同的命名空间,并且,是的,Python 认为您正在尝试从模块继承。

变化:

class MainPage(BaseHandler):

到:

class MainPage(BaseHandler.BaseHandler):

你应该很高兴。这样,您的意思是“请从 BaseHandler 模块中的 BaseHandler 类继承”。

或者,您可以更改:

import BaseHandler

到:

from BaseHandler import BaseHandler

【讨论】:

【参考方案2】:

首先文件名应该全部小写。这是 Python 的约定,至少在大多数情况下有助于避免这样的混淆。

接下来,您从 withing MainHandler.py 导入是错误的。您正在导入BaseHandler(模块)并像引用它一样引用它是一个类。该类实际上是BaseHandler.BaseHandler。你需要这样引用它。

试试吧,它应该适合你。

【讨论】:

以上是关于Python:类名与文件/模块名相同导致继承问题?的主要内容,如果未能解决你的问题,请参考以下文章

多继承及魔术方法介绍

报错模块没有某个属性

python--面向对象之三个特性:封装继承多态

java类的继承

Python之类

Java编译单元为什么只能有一个public类,而且源文件名必须要与类名相同