Can';不要在Python 3中使用抽象类(ABCMeta)
我正在使用SQLAlchemy创建一个Flask RESTful应用程序 我正在努力使用Python 3中的抽象类概念。根据python文档()的规定,用法应该简单到:Can';不要在Python 3中使用抽象类(ABCMeta),python,python-3.x,abstract-class,flask-restful,Python,Python 3.x,Abstract Class,Flask Restful,我正在使用SQLAlchemy创建一个Flask RESTful应用程序 我正在努力使用Python 3中的抽象类概念。根据python文档()的规定,用法应该简单到: ### Python documentation ### class Foo: def __getitem__(self, index): ... def __len__(self): ... def get_iterator(self): return i
### Python documentation ###
class Foo:
def __getitem__(self, index):
...
def __len__(self):
...
def get_iterator(self):
return iter(self)
class MyIterable(metaclass=ABCMeta):
@abstractmethod
def __iter__(self):
while False:
yield None
def get_iterator(self):
return self.__iter__()
@classmethod
def __subclasshook__(cls, C):
if cls is MyIterable:
if any("__iter__" in B.__dict__ for B in C.__mro__):
return True
return NotImplemented
MyIterable.register(Foo)
但是,在我的包内实现中,我收到以下错误:
文件:api.base\u api.py
class BaseAPI(metaclass=ABCMeta):
@property
@abstractmethod
def entity(self):
pass
def checkId(self, unique_id):
try:
if not unique_id:
abort(405)
obj = self.entity.get_valid(int(unique_id))
if not obj:
raise Exception('%s nao encontrado' % (self.__class__.__name__))
return obj
except:
abort(404)
...
class ProjectAPI(Resource):
@property
def entity(self):
return Projeto #this is my model class object
def get(self, unique_id=unique_id):
obj self.checkId(unique_id)
return {self.entity.__api_name__: obj.serialize()}
#the return (tested before) is like {"projects": project.data})
...
from apis.base_api import BaseAPI
from apis.projects import ProjectAPI
BaseAPI.register(ProjectAPI)
文件:api.projects.py
class BaseAPI(metaclass=ABCMeta):
@property
@abstractmethod
def entity(self):
pass
def checkId(self, unique_id):
try:
if not unique_id:
abort(405)
obj = self.entity.get_valid(int(unique_id))
if not obj:
raise Exception('%s nao encontrado' % (self.__class__.__name__))
return obj
except:
abort(404)
...
class ProjectAPI(Resource):
@property
def entity(self):
return Projeto #this is my model class object
def get(self, unique_id=unique_id):
obj self.checkId(unique_id)
return {self.entity.__api_name__: obj.serialize()}
#the return (tested before) is like {"projects": project.data})
...
from apis.base_api import BaseAPI
from apis.projects import ProjectAPI
BaseAPI.register(ProjectAPI)
文件:API.\uuuu init\uuuuu.py
class BaseAPI(metaclass=ABCMeta):
@property
@abstractmethod
def entity(self):
pass
def checkId(self, unique_id):
try:
if not unique_id:
abort(405)
obj = self.entity.get_valid(int(unique_id))
if not obj:
raise Exception('%s nao encontrado' % (self.__class__.__name__))
return obj
except:
abort(404)
...
class ProjectAPI(Resource):
@property
def entity(self):
return Projeto #this is my model class object
def get(self, unique_id=unique_id):
obj self.checkId(unique_id)
return {self.entity.__api_name__: obj.serialize()}
#the return (tested before) is like {"projects": project.data})
...
from apis.base_api import BaseAPI
from apis.projects import ProjectAPI
BaseAPI.register(ProjectAPI)
没有“编译”错误,应用程序开始运行。当我尝试访问ProjectAPI时,我得到一个错误:
AttributeError:“ProjectAPI”对象没有属性“checkId”
既然我注册了BaseAPI.checkid方法,它不应该抽象地继承到ProjectAPI吗?我做错了什么
提前Tnx
发现了一个错误 当从我的BaseAPI类(换句话说,从我的抽象类创建我的具体类)创建ProjectAPI类时,我应该使用Python 3语法,扩展抽象类:
class ProjectAPI(BaseAPI, Resource):
...
并且不应在BaseAPI上注册项目API
尽管如此,即使修复了此问题,仍会出现以下错误:
TypeError:元类冲突:派生类的元类必须是其所有基元类的(非严格)子类
两件事:请修复问题中的缩进,并确保不要将
checkid
与checkid
混淆,因为Python区分大小写。@chepner我正在修复缩进,以为它只在复制代码时发生。我把函数也错放在这里了。TnxI发现资源扩展是问题的根源,因为删除它会使具体的实例化工作正常。看来Resource
已经在使用元类了。修复方法应该是创建一个新的元类,该元类扩展了ABCMeta
和Resource
使用的任何内容,并将其用作ProjectAPI
的元类。