从另一个 class 调用一个 class 方法导致元 class 冲突
Calling a class method from another class causes metaclass conflict
我有一个 Python 网络应用程序,我想定义一个通用 class 或函数来处理网页,并从更具体的 class 调用它以用于特定页面实例。
错误:
metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases
我已经检查了关于该错误消息的所有 Whosebug 问题和答案,但不理解所给出的解释(我发现了一篇关于 metaclasses 的文章,但我不明白 - OOP 并不是真正的我的东西)。我还查看了所有关于从另一个 class 调用 class 方法的 Whosebug 问题和答案(我也不理解它们)。
代码:
import webapp2
from datetime import datetime, timedelta
from google.appengine.ext import ndb
from google.appengine.api import users
import admin_templates
import authenticate
class myPage(webapp2.RequestHandler):
def get(pageInstance):
pageInstance.outputHtml()
def outputHtml(pageInstance,pageTitle,pageContent):
adminLink = authenticate.get_adminlink()
authMessage = authenticate.get_authmessage()
adminNav = authenticate.get_adminnav()
pageInstance.response.headers['Content-Type'] = 'text/html'
html = admin_templates.base
html = html.replace('#title#', pageTitle)
html = html.replace('#authmessage#', authMessage)
html = html.replace('#adminlink#', adminLink)
html = html.replace('#adminnav#', adminNav)
html = html.replace('#content#', pageContent)
pageInstance.response.out.write(html)
pageInstance.response.out.write(admin_templates.footer)
class AuditorsPage(webapp2.RequestHandler, myPage.outputHtml):
def get(self):
self.output_auditors()
def output_auditors(self):
self.outputHtml(admin_templates.auditors_title, admin_templates.auditors_content)
如何从 AuditorsPage
class 中调用 myPage
class 中的 outputHtml
方法而不出现元 class 错误?
试试这个:
myPage.outputHtml()
而不是:
self.outputHtml()
根据你的问题,我猜你想继承myPage的方法。如果是这样,而不是:
class AuditorsPage(webapp2.RequestHandler, myPage.outputHtml):
尝试:
class AuditorsPage(webapp2.RequestHandler, myPage):
Class AuditorsPage
可以继承自 myPage
import webapp2
from datetime import datetime, timedelta
from google.appengine.ext import ndb
from google.appengine.api import users
import admin_templates
import authenticate
class myPage(webapp2.RequestHandler):
def get(pageInstance):
pageInstance.outputHtml()
def outputHtml(pageInstance,pageTitle,pageContent):
adminLink = authenticate.get_adminlink()
authMessage = authenticate.get_authmessage()
adminNav = authenticate.get_adminnav()
pageInstance.response.headers['Content-Type'] = 'text/html'
html = admin_templates.base
html = html.replace('#title#', pageTitle)
html = html.replace('#authmessage#', authMessage)
html = html.replace('#adminlink#', adminLink)
html = html.replace('#adminnav#', adminNav)
html = html.replace('#content#', pageContent)
pageInstance.response.out.write(html)
pageInstance.response.out.write(admin_templates.footer)
class AuditorsPage(myPage):
def get(self):
self.output_auditors()
然后可以实例化AuditorsPage()直接调用outputHtml
foo = AuditorsPage()
foo.outputHtml(admin_templates.auditors_title, admin_templates.auditors_content)
好的,所以您没有为 AuditorsPage 调用 super:
class myPage():
def __init__(self):
pass
def outputHtml(self):
print("outputHTML")
class AuditorsPage(myPage):
def __init__(self):
super().__init__()
def output(self):
print("AuditorsPage")
我正在使用一个非常精简的版本来解释发生了什么。如您所见,我们有您的 myClass class。从 AuditorsPage 创建对象时,我们现在可以按预期访问方法 outputHTML。希望这可以帮助。
错误是因为您正在从通用 class 中的方法子classing 您的 class,这是无法完成的。实际上,您的代码是错误的,至少有两种方法可以修复它:
1) 而是从 myPage 继承:在这种情况下,它不会工作并且会带来 MRO 错误,因为您的方法不是 class 的任何实例的一部分,因为它们没有链接到使用 self
作为第一个参数的对象。
这是您的代码在这种情况下的修复方法:
from google.appengine.ext import ndb
from google.appengine.api import users
import admin_templates
import authenticate
class myPage(webapp2.RequestHandler):
def get(self, pageInstance):
pageInstance.outputHtml()
def outputHtml(self, pageInstance,pageTitle,pageContent):
adminLink = authenticate.get_adminlink()
authMessage = authenticate.get_authmessage()
adminNav = authenticate.get_adminnav()
pageInstance.response.headers['Content-Type'] = 'text/html'
html = admin_templates.base
html = html.replace('#title#', pageTitle)
html = html.replace('#authmessage#', authMessage)
html = html.replace('#adminlink#', adminLink)
html = html.replace('#adminnav#', adminNav)
html = html.replace('#content#', pageContent)
pageInstance.response.out.write(html)
pageInstance.response.out.write(admin_templates.footer)
class AuditorsPage(myPage):
def get(self):
self.output_auditors()
2) 将myPage class 中的两个方法作为没有class 的普通方法获取,然后直接从您的class 中调用它们。实际上,你只需要 create outputHtml()
方法,然后从你的 RequestHandler subclass 中的方法直接调用它(没有 self.
)。
我有一个 Python 网络应用程序,我想定义一个通用 class 或函数来处理网页,并从更具体的 class 调用它以用于特定页面实例。
错误:
metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases
我已经检查了关于该错误消息的所有 Whosebug 问题和答案,但不理解所给出的解释(我发现了一篇关于 metaclasses 的文章,但我不明白 - OOP 并不是真正的我的东西)。我还查看了所有关于从另一个 class 调用 class 方法的 Whosebug 问题和答案(我也不理解它们)。
代码:
import webapp2
from datetime import datetime, timedelta
from google.appengine.ext import ndb
from google.appengine.api import users
import admin_templates
import authenticate
class myPage(webapp2.RequestHandler):
def get(pageInstance):
pageInstance.outputHtml()
def outputHtml(pageInstance,pageTitle,pageContent):
adminLink = authenticate.get_adminlink()
authMessage = authenticate.get_authmessage()
adminNav = authenticate.get_adminnav()
pageInstance.response.headers['Content-Type'] = 'text/html'
html = admin_templates.base
html = html.replace('#title#', pageTitle)
html = html.replace('#authmessage#', authMessage)
html = html.replace('#adminlink#', adminLink)
html = html.replace('#adminnav#', adminNav)
html = html.replace('#content#', pageContent)
pageInstance.response.out.write(html)
pageInstance.response.out.write(admin_templates.footer)
class AuditorsPage(webapp2.RequestHandler, myPage.outputHtml):
def get(self):
self.output_auditors()
def output_auditors(self):
self.outputHtml(admin_templates.auditors_title, admin_templates.auditors_content)
如何从 AuditorsPage
class 中调用 myPage
class 中的 outputHtml
方法而不出现元 class 错误?
试试这个:
myPage.outputHtml()
而不是:
self.outputHtml()
根据你的问题,我猜你想继承myPage的方法。如果是这样,而不是:
class AuditorsPage(webapp2.RequestHandler, myPage.outputHtml):
尝试:
class AuditorsPage(webapp2.RequestHandler, myPage):
Class AuditorsPage
可以继承自 myPage
import webapp2
from datetime import datetime, timedelta
from google.appengine.ext import ndb
from google.appengine.api import users
import admin_templates
import authenticate
class myPage(webapp2.RequestHandler):
def get(pageInstance):
pageInstance.outputHtml()
def outputHtml(pageInstance,pageTitle,pageContent):
adminLink = authenticate.get_adminlink()
authMessage = authenticate.get_authmessage()
adminNav = authenticate.get_adminnav()
pageInstance.response.headers['Content-Type'] = 'text/html'
html = admin_templates.base
html = html.replace('#title#', pageTitle)
html = html.replace('#authmessage#', authMessage)
html = html.replace('#adminlink#', adminLink)
html = html.replace('#adminnav#', adminNav)
html = html.replace('#content#', pageContent)
pageInstance.response.out.write(html)
pageInstance.response.out.write(admin_templates.footer)
class AuditorsPage(myPage):
def get(self):
self.output_auditors()
然后可以实例化AuditorsPage()直接调用outputHtml
foo = AuditorsPage()
foo.outputHtml(admin_templates.auditors_title, admin_templates.auditors_content)
好的,所以您没有为 AuditorsPage 调用 super:
class myPage():
def __init__(self):
pass
def outputHtml(self):
print("outputHTML")
class AuditorsPage(myPage):
def __init__(self):
super().__init__()
def output(self):
print("AuditorsPage")
我正在使用一个非常精简的版本来解释发生了什么。如您所见,我们有您的 myClass class。从 AuditorsPage 创建对象时,我们现在可以按预期访问方法 outputHTML。希望这可以帮助。
错误是因为您正在从通用 class 中的方法子classing 您的 class,这是无法完成的。实际上,您的代码是错误的,至少有两种方法可以修复它:
1) 而是从 myPage 继承:在这种情况下,它不会工作并且会带来 MRO 错误,因为您的方法不是 class 的任何实例的一部分,因为它们没有链接到使用 self
作为第一个参数的对象。
这是您的代码在这种情况下的修复方法:
from google.appengine.ext import ndb
from google.appengine.api import users
import admin_templates
import authenticate
class myPage(webapp2.RequestHandler):
def get(self, pageInstance):
pageInstance.outputHtml()
def outputHtml(self, pageInstance,pageTitle,pageContent):
adminLink = authenticate.get_adminlink()
authMessage = authenticate.get_authmessage()
adminNav = authenticate.get_adminnav()
pageInstance.response.headers['Content-Type'] = 'text/html'
html = admin_templates.base
html = html.replace('#title#', pageTitle)
html = html.replace('#authmessage#', authMessage)
html = html.replace('#adminlink#', adminLink)
html = html.replace('#adminnav#', adminNav)
html = html.replace('#content#', pageContent)
pageInstance.response.out.write(html)
pageInstance.response.out.write(admin_templates.footer)
class AuditorsPage(myPage):
def get(self):
self.output_auditors()
2) 将myPage class 中的两个方法作为没有class 的普通方法获取,然后直接从您的class 中调用它们。实际上,你只需要 create outputHtml()
方法,然后从你的 RequestHandler subclass 中的方法直接调用它(没有 self.
)。