抽象类和 PyMongo;无法实例化抽象类 [英] Abstract classes and PyMongo; can't instantiate abstract class

查看:43
本文介绍了抽象类和 PyMongo;无法实例化抽象类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我创建了空抽象类 AbstractStorage 并从它继承了 Storage 类:

导入 abc将 pymongo 导入为 mongo主机 = mongo.MongoClient()打印(host.alive()) # 真类抽象存储(元类= abc.ABCMeta):经过类存储(抽象存储):dbh = 主机def __init__(self):打印('__init__')贮存()

我希望输出是

真__在里面__

然而,我得到的是

真回溯(最近一次调用最后一次): 中的文件/home/vaultah/run.py",第 16 行贮存()类型错误:无法使用抽象方法 dbh 实例化抽象类 Storage

如果我删除 metaclass=abc.ABCMeta(以便 AbstractStorage 成为普通类)和/或如果我设置 ,问题(显然)就会消失dbh 为其他值.

这是怎么回事?

解决方案

这真的不是 ABC 的问题,而是 PyMongo 的问题.此处存在一个问题.pymongo 似乎覆盖了 __getattr__ 以返回某种数据库类.这意味着 host.__isabstractmethod__ 返回一个 Database 对象,这在布尔上下文中为真.这导致 ABCMeta 认为 host 是一个抽象方法:

<预><代码>>>>布尔(主机.__isabstractmethod__)真的

问题报告中描述的解决方法是在您的对象上手动设置 host.__isabstractmethod__ = False.关于该问题的最后一条评论表明已针对 pymongo 3.0 进行了修复.

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()

I expected the output to be

True
__init__

however, the one I'm getting is

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

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.

What's going on here?

解决方案

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

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆