标签: abc

为什么集合ABC模块中的Callable ABC?

Python collections.abc模块包含许多方便的ABC,用于检查对象的各种功能,但似乎不属于Callable.没有标准集合可以调用,并且PEP 3119不提供任何推理甚至提及可调用ABC,那么为什么它在这个包中而不是在其他地方呢?

上下文:我正在编写一个Python-> Java编译器以获得乐趣,我只是想看看决策背后是否有任何推理,所以我可以在我的代码中列出该推理.

python abc

9
推荐指数
1
解决办法
1878
查看次数

具有不同参数量的抽象类

我想知道在使用抽象方法创建抽象类时是否可能,如果它可以允许派生类中的那些方法的实现为每个函数提供不同数量的参数.

我目前有抽象课

from abc import ABCMeta, abstractmethod

class View(metaclass=ABCMeta):
    @abstractmethod
    def set(self):
        pass

    @abstractmethod
    def get(self):
        pass
Run Code Online (Sandbox Code Playgroud)

但是我希望能够在一个类中实现它,set有1个参数并且得到2(set(param1)get(param1, param2)),然后在另一个类中也继承它但是有0个参数set,2个用于get (set()get(param1, param2)).

这是可能的,如果是这样,我将如何去做

python abc python-3.x

9
推荐指数
2
解决办法
5134
查看次数

为什么`__subclasshook__`可以被monkeypatched到元类上,但`__instancecheck__`不能?

这是一个尝试创建装饰器的玩具示例,该装饰器允许声明属性名称,这些属性名称应该是标准__subclasshook____instancecheck__模式中"接口检查"的必要部分.

当我装饰这个Foo类时,它似乎按预期工作.我创建了一个Bar与之无关的类,Foo但它具有所需的属性,并且它正确地满足isinstance(instance_of_bar, Foo) == True.

但是作为另一个例子,我创建了一个dict扩充的子类,以便key可以使用getattr语法访问这些值(例如dict,d['a']可以替换d.a为可获得相同结果的where ).在这种情况下,属性只是实例属性,因此__instancecheck__应该工作.

这是代码.请注意,鉴于具有Bar工作实例的示例,将__subclasshook__函数"monkeypatch"选择到Foo类(具有元类)中的选择正常.因此,似乎不必直接在元类的类定义中定义函数.

#Using Python 2.7.3

import abc
def interface(*attributes):
    def decorator(Base):

        def checker(Other):
            return all(hasattr(Other, a) for a in attributes)

        def __subclasshook__(cls, Other):
            if checker(Other):
                return True
            return NotImplemented

        def __instancecheck__(cls, Other):
            return checker(Other)

        Base.__subclasshook__ = classmethod(__subclasshook__)
        Base.__instancecheck__ = classmethod(__instancecheck__) …
Run Code Online (Sandbox Code Playgroud)

python interface subclass abc

8
推荐指数
1
解决办法
2084
查看次数

如何将abc.abstractproperty与classmethod结合起来制作"抽象类属性"?

我想创建一个在抽象基类中声明的"类属性",然后在具体的实现类中重写,同时保持实现必须覆盖抽象基类的类属性的可爱断言.

虽然我看了一下这个问题,但我天真地尝试重新接受已接受的答案却没有用:

>>> import abc
>>> class ClassProperty(abc.abstractproperty):
...     def __get__(self, cls, owner):
...             return self.fget.__get__(None, owner)()
...
>>> class Base(object):
...     __metaclass__ = abc.ABCMeta
...     @ClassProperty
...     def foo(cls):
...             raise NotImplementedError
...
>>> class Impl(Base):
...     @ClassProperty
...     def foo(cls):
...             return 5
...
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/2rs2ts/src/myproj/env/lib/python2.7/abc.py", line 94, in __new__
    value = getattr(cls, name, None)
  File "<stdin>", line 3, in __get__
TypeError: Error when calling …
Run Code Online (Sandbox Code Playgroud)

python abc

8
推荐指数
1
解决办法
389
查看次数

为什么在元类派生自 ABCMeta 的类中需要使用@abstractmethod?

PEP 3119指出:

所述@abstractmethod装饰应仅在类体中使用,并且仅用于一个其元类是(衍生自)ABCMeta。不支持将抽象方法动态添加到类,或在方法或类创建后尝试修改其抽象状态。

然而,我找不到解释为什么会这样。具体来说,仅@abstractmethod在未显式继承自ABCMeta. 在下面的简单例子中,如果我理解正确,正确的做事方法是:

import six
from abc import ABCMeta
from abc import abstractmethod

class Base(six.with_metaclass(ABCMeta)):
    def __init__(self):
        print('Init abstract base')

    @abstractmethod
    def do_something(self):
        pass

class Subclass(Base):
    def __init__(self):
        super(Subclass, self).__init__()

    def do_something(self):
        print('Done.')

sub = Subclass()
sub.do_something()
Run Code Online (Sandbox Code Playgroud)

但是,如果我让Base类简单地从 继承object,并且仅在需要时使用装饰器,我会注意到行为没有变化。

from abc import abstractmethod

class Base(object):
    def __init__(self):
        print('Init abstract base')

    @abstractmethod
    def do_something(self):
        pass

class Subclass(Base):
    def __init__(self):
        super(Subclass, self).__init__()

    def do_something(self):
        print('Done.')

sub = …
Run Code Online (Sandbox Code Playgroud)

python inheritance abstract-class abc python-decorators

8
推荐指数
1
解决办法
2138
查看次数

两级抽象类层次结构没有“一致的方法解析”错误

我需要两个级别的抽象类和第三个级别的具体类:

from abc import ABC

class Shape(ABC):
...

class Quad(ABC, Shape):
...

class Square(Quadrilateral)
...
Run Code Online (Sandbox Code Playgroud)

此代码TypeError: Cannot create a consistent method resolution根据 的声明生成Quad。我意识到问题是多重继承的歧义。 Quad不知道是否直接从ABC或 从派生某些函数Shape,但如何修复它?我不能ABCQuad的声明中删除,因为那样它就不再是抽象的了。

python multiple-inheritance abc python-3.x

8
推荐指数
1
解决办法
1837
查看次数

抽象基类和异常

问题

为什么使用该子句Exception创建的抽象的虚拟子类ABCMeta.register不匹配except

背景

我想确保我正在使用的包抛出的异常被转换为MyException,以便导入我的模块的代码可以捕获我的模块抛出的任何异常,except MyException:这样except Exception它们就不必依赖于实现细节(我正在使用第三方包的事实)。

例子

为此,我尝试使用抽象基类注册OtherException为:MyException

# Tested with python-3.6
from abc import ABC

class MyException(Exception, ABC):
    pass

class OtherException(Exception):
    """Other exception I can't change"""
    pass

MyException.register(OtherException)

assert issubclass(OtherException, MyException)  # passes

try:
    raise OtherException("Some OtherException")
except MyException:
    print("Caught MyException")
except Exception as e:
    print("Caught Exception: {}".format(e))
Run Code Online (Sandbox Code Playgroud)

断言通过(如预期),但异常发生在第二个块上:

Caught Exception: Some OtherException
Run Code Online (Sandbox Code Playgroud)

python abc python-3.x

8
推荐指数
2
解决办法
1904
查看次数

从 ABC 和 django.db.models.Model 继承都会引发元类异常

我正在尝试使用 Python 3 实现一个 Django 数据模型类,它也是一个接口类。我这样做的原因是,我正在为我的同事编写一个基类,并且需要他在所有这些中实现三个方法他从我的派生的类。我试图给他一种简化的方式来使用我设计的系统的功能。但是,他必须重写一些方法来为系统提供足够的信息来执行他继承的类中的代码。

我知道这是错误的,因为它会抛出异常,但我想要一个类似以下示例的类:

from django.db import models
from abc import ABC, abstractmethod

class AlgorithmTemplate(ABC, models.Model):
    name = models.CharField(max_length=32)

    @abstractmethod
    def data_subscriptions(self):
        """
        This method returns a list of topics this class will subscribe to using websockets

        NOTE: This method MUST be overriden!
        
        :rtype: list
        """
Run Code Online (Sandbox Code Playgroud)

我知道我可以避免继承 ABC类,但我想使用它是因为我不会在这里让你感到厌烦。

问题


在将一个类(如上面的类)包含到我的项目中并运行后,python manage.py makemigrations我收到错误:TypeError: metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases. …

abc django-models python-3.x

8
推荐指数
2
解决办法
1662
查看次数

Python abc模块:扩展抽象基类和异常派生类会导致令人惊讶的行为

扩展抽象基类和从"对象"派生的类可以正常工作:如果您尚未实现所有抽象方法和属性,则会出现错误.

奇怪的是,用扩展"Exception"的类替换对象派生类允许您创建不实现所有必需的抽象方法和属性的类的实例.

例如:

import abc

# The superclasses
class myABC( object ):
    __metaclass__ = abc.ABCMeta

    @abc.abstractproperty
    def foo(self):
        pass

class myCustomException( Exception ):
    pass

class myObjectDerivedClass( object ):
    pass

# Mix them in different ways
class myConcreteClass_1(myCustomException, myABC):
    pass

class myConcreteClass_2(myObjectDerivedClass, myABC):
    pass

# Get surprising results
if __name__=='__main__':
    a = myConcreteClass_1()
    print "First instantiation done. We shouldn't get this far, but we do."
    b = myConcreteClass_2()
    print "Second instantiation done. We never reach here, which is good."
Run Code Online (Sandbox Code Playgroud)

... ...产量 …

python abstract-class exception multiple-inheritance abc

7
推荐指数
1
解决办法
612
查看次数

带有抽象基类的 Python 类型提示

我有一个 ABC 方法,子类应该返回他们自己的类型,我正在尝试找出最好的方法来提示这个。例如:

from abc import ABC, abstractmethod

class Base(ABC):
    @abstractmethod
    def f(self): ## here i want a type hint for type(self)
        pass

class Blah(Base):
    def __init__(self, x: int):
        self.x = x

    def f(self) -> "Blah":
        return Blah(self.x + 1)
Run Code Online (Sandbox Code Playgroud)

我能想到的最好的是这个,它有点沉重:

from abc import ABC, abstractmethod
from typing import TypeVar, Generic

SELF = TypeVar["SELF"]

class Base(ABC, Generic[SELF]):

    @abstractmethod
    def f(self) -> SELF:
        pass

class Blah(Base["Blah"]):

    def __init__(self, x: int):
        self.x = x

    def f(self) -> "Blah":
        return Blah(self.x+1)
Run Code Online (Sandbox Code Playgroud)

我有更好/更清洁的方法吗?

python abc type-hinting

7
推荐指数
1
解决办法
679
查看次数