抽象类和PyMongo;无法实例化抽象类 [英] Abstract classes and PyMongo; can't instantiate abstract class
问题描述
我创建了一个空的抽象类 AbstractStorage
,并从其中继承了 Storage
类:
I created the empty abstract class AbstractStorage
and inherited the Storage
class from it:
import abc
import pymongo as mongo
host = mongo.MongoClient()
print(host.alive()) # True
class AbstractStorage(metaclass=abc.ABCMeta):
pass
class Storage(AbstractStorage):
dbh = host
def __init__(self):
print('__init__')
Storage()
我期望输出为
True
__init__
但是,我得到的是
True
Traceback (most recent call last):
File "/home/vaultah/run.py", line 16, in <module>
Storage()
TypeError: Can't instantiate abstract class Storage with abstract methods dbh
如果我删除 metaclass = abc.ABCMeta
(显然, AbstractStorage
普通类)和/或(如果我将 dbh
设置为其他值)。
The problem (apparently) goes away if I remove metaclass=abc.ABCMeta
(so that AbstractStorage
becomes an ordinary class) and/or if I set dbh
to some other value.
这是怎么回事?
推荐答案
ABC的问题,PyMongo的问题。 此处,有一个问题。似乎pymongo会覆盖 __ getattr __
以返回某种数据库类。这意味着 host .__ isabstractmethod __
返回一个Database对象,在布尔上下文中为true。这导致ABCMeta相信主机
是一种抽象方法:
This isn't really a problem with ABCs, it's a problem with PyMongo. There is an issue about it here. It seems that pymongo overrides __getattr__
to return some sort of database class. This means that host.__isabstractmethod__
returns a Database object, which is true in a boolean context. This cause ABCMeta to believe that host
is an abstract method:
>>> bool(host.__isabstractmethod__)
True
问题报告中描述的解决方法是手动在对象上设置 host .__ isabstractmethod__ = False
。关于这个问题的最后评论表明,已经针对pymongo 3.0进行了修复。
The workaround described in the issue report is to manually set host.__isabstractmethod__ = False
on your object. The last comment on the issue suggests a fix has been put in for pymongo 3.0.
这篇关于抽象类和PyMongo;无法实例化抽象类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!