从另一个 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.)。