2017-04-06 71 views
1

我有一个Python Web应用程序,我想定义一个通用的类或函数来处理网页,并从特定的页面实例的更具体的类中调用它。调用另一个类的类方法导致元类冲突

错误:

metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases

我已经检查了所有的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方法从AuditorsPagemyPage类没有得到一个元类错误?

+1

为什么'AuditorsPage'尝试从'myPage'的*方法*继承? – chepner

+0

没有特别的理由!只是我无能为力! –

+0

感谢编辑@bruntime,这是一个进步 –

回答

1

错误来自您从一般类中的方法继承类,这是无法完成的。其实,你的代码是错误的,至少有两种方法可以修复它:

1)继承myPage代替:在这种情况下,它不起作用,并且会带来MRO错误,因为你的方法不是是类的任何实例的一部分,因为它们没有链接到使用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)刚刚得到在我的页面类为没有分类标准方法,这两种方法,然后直接从你的类调用它们。实际上,你只需要create outputHtml()方法,然后直接调用它(不包括self.)从RequestHandler子类中的方法。

+0

谢谢 - 我用你的第一个建议 –

1

试试这个:而不是

myPage.outputHtml() 

:在您的问题

​​
0

基地,我想你要继承我的编目方法。如果是这样的话,而不是:

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

尝试:

class AuditorsPage(webapp2.RequestHandler, myPage): 
+0

我尝试这样做,得到了以下错误:'类型错误:错误调用元类基地 无法创建基地MYPAGE一致的方法解决 顺序(MRO)时,RequestHandler' –

+1

那并没有帮助,因为类'myPage'中的方法没有'self'作为第一个参数,因此Python无法找出它们的MRO。 – mydaemon

+0

废话。 @mydaemon是正确的。 –

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) 
+0

这是非常接近,但它仍然抛出一个错误,我认为,因为你需要一种方法,而不是一个属性。 –

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方法。希望这可以帮助。