从另一个类调用类方法会导致元类冲突

时间:2017-04-06 15:01:22

标签: python metaclass

我有一个Python Web应用程序,我想定义一个用于处理网页的通用类或函数,并从特定页面实例的更具体的类中调用它。

错误:

  

元类冲突:派生类的元类必须是其所有基类的元类的(非严格)子类

我已经检查了所有StackOverflow问题&关于那个错误信息的答案并且不理解给出的解释(我发现了一篇关于我不理解的元类的文章--OOP并不是我的事情)。我还查看了所有StackOverflow问题&关于从另一个类调用类方法的答案(并且也不理解它们)。

代码:

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)

如何从outputHtml类调用myPage类中的AuditorsPage方法而不会出现元类错误?

5 个答案:

答案 0 :(得分:1)

试试这个:

myPage.outputHtml()

而不是:

self.outputHtml()

答案 1 :(得分:1)

班级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)

答案 2 :(得分:1)

好的,所以你没有为AuditorsPage调用超级:

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类。从AuditorsPage创建对象时,我们现在可以按预期访问outputHTML方法。希望这可以帮助。

答案 3 :(得分:1)

错误来自于您从一般类中的方法继承类的事实,这是无法完成的。实际上,您的代码是错误的,并且至少有两种方法可以解决它:

1)继承自myPage:在这种情况下,它将无法工作并将带来MRO错误,因为您的方法不是该类的任何实例的一部分,因为它们没有使用{{1链接到对象}}作为第一个参数。

在这种情况下,这是代码的修复:

self

2)只需将myPage类中的两个方法作为没有类的常规方法获取,然后直接从类中调用它们。实际上,您只需要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() 方法,然后直接从RequestHandler子类中的方法调用它(不带create outputHtml())。

答案 4 :(得分:0)

根据你的问题,我想你想从myPage继承方法。如果是这种情况,而不是:

class AuditorsPage(webapp2.RequestHandler, myPage.outputHtml):

尝试:

class AuditorsPage(webapp2.RequestHandler, myPage):