抽象类和PyMongo; 无法实例化抽象类
我创建了一个空的抽象类,AbstractStorage
并Storage
从中继承了该类:
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
了其他值,问题(显然)就消失了。
这里发生了什么?
-
这实际上不是ABC的问题,而是PyMongo的问题。有一个关于它的问题在这里。似乎pymongo重写
__getattr__
以返回某种数据库类。这意味着将host.__isabstractmethod__
返回一个数据库对象,该对象在布尔上下文中为true。这使ABCMeta认为这host
是一种抽象方法:>>> bool(host.__isabstractmethod__) True
问题报告中描述的解决方法是
host.__isabstractmethod__ = False
在对象上手动设置。关于这个问题的最后评论表明,已经为pymongo 3.0修复了问题。