标签: abc

Python:子类`type`来创建专门的类型(例如"int"列表)

我正在尝试子类化type以创建一个允许构建专用类型的类.例如ListType:

>>> ListOfInt = ListType(list, value_type=int)
>>> issubclass(ListOfInt, list)
True
>>> issubclass(list, ListOfInt)
False
>>> # And so on ...
Run Code Online (Sandbox Code Playgroud)

但是,这ListOfInt永远不会用于创建实例!我只是将它用作type我可以操作以与其他类型进行比较的实例...特别是在我的情况下,我需要查找合适的操作,根据输入的类型,我需要的类型为包含更多精度(如list of intXML string等).

所以这就是我提出的:

class SpzType(type):

    __metaclass__ = abc.ABCMeta

    @classmethod
    def __subclasshook__(cls, C):
        return NotImplemented

    def __new__(cls, base, **features):
        name = 'SpzOf%s' % base.__name__
        bases = (base,)
        attrs = {}
        return super(SpzType, cls).__new__(cls, name, bases, attrs)

    def __init__(self, base, **features):
        for name, value in features.items():
            setattr(self, name, …
Run Code Online (Sandbox Code Playgroud)

python abc

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

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
查看次数

如何在Sphinx文档中将成员注释为抽象?

以下两个属性定义在Sphinx autodoc html输出中显示完全相同:

@property
def concrete(self):
    """This is the concrete docstring"""
    pass

@abstractproperty
def abstract(self):
    """This is the abstract docstring"""
    pass
Run Code Online (Sandbox Code Playgroud)

Sphinx是否有办法用某种标识符注释抽象方法?我希望在我的文档中可以明显看出我的ABC成员需要实现哪些,以及一旦定义了所需的,就会获得mixin免费赠品.

python documentation abc python-sphinx

6
推荐指数
1
解决办法
606
查看次数

查找注册类的所有抽象基类

如何找到给定类是"虚拟子类"的所有抽象基类?

换句话说,我正在寻找一个virtual_base_classes()像这样的魔术函数:

>>> for cls in virtual_base_classes(list):
>>>   print(cls)
<class 'collections.abc.MutableSequence'>
<class 'collections.abc.Sequence'>
<class 'collections.abc.Sized'>
<class 'collections.abc.Iterable'>
<class 'collections.abc.Container'>
Run Code Online (Sandbox Code Playgroud)

(我不知道所有注册的abclist,所以上面的例子可能不完整.)

请注意,并非每个抽象基类都将被定义collections.abc.有一个模块abc(不同于collections.abc)提供了元类ABCMeta.任何类都是ABCMeta使用标准接口(register方法)支持"虚拟子类"注册的实例.没有什么可以阻止某人(程序员或Python库)创建一个ABCMeta不属于的实例collections.abc.

python abstract-class subclass abc python-3.x

6
推荐指数
1
解决办法
955
查看次数

Python 中具有特定参数的抽象方法

我用 abc 包实现了抽象类。下面的程序显示没有问题。

有没有办法让它失败,因为抽象MyMethod确实有一个参数,a但类中的“MyMethod”的实现Derivative没有?所以我不仅要指定接口类中的方法,还要指定Base这些方法的参数。

import abc

#Abstract class
class Base(object):
    __metaclass__  = abc.ABCMeta

    @abc.abstractmethod
    def MyMethod(self, a):
        'MyMethod prints a'


class Derivative(Base)

    def MyMethod(self):
        print 'MyMethod'
Run Code Online (Sandbox Code Playgroud)

python oop class abc abstract

6
推荐指数
1
解决办法
4810
查看次数

如何使用abc抽象基类作为模拟规范?

我有一个抽象基类:

import abc
import six

@six.add_metaclass(abc.ABCMeta)
class A(object):

    @abc.abstractmethod
    def f(self, arg1):
        pass
Run Code Online (Sandbox Code Playgroud)

我想使用此类作为模拟的规范。

import mock
mock_a = mock.Mock(spec=A)
Run Code Online (Sandbox Code Playgroud)

这部分起作用。例如,mock_a.x结果为AttribureError("Mock object has no attribute 'x')。但是mock_a.f,并未基于的抽象方法进行说明A.f。无论传递给的参数数量如何,它都会返回一个模拟f

mock_a = mock.Mock(spec=A)

# Succeeds
print mock_a.f(1)

# Should fail, but returns a mock
print mock_a.f(1,2)

# Correctly fails
print mock_a.x
Run Code Online (Sandbox Code Playgroud)

模拟可以创建speced一个模拟A.fcreate_autospec...

f_spec = mock.create_autospec(A.f)

# Succeeds
f_spec(mock_a, 1)

# Correctly fails
f_spec(mock_a, 1, 2)
Run Code Online (Sandbox Code Playgroud)

...但是对于A的属性却不这样做

如何创建可以准确实现抽象基类的模拟?

python abc python-mock

6
推荐指数
1
解决办法
797
查看次数

是否有一种python方式将“对象和列表”之类的“序列”对象与“字节和str”之类的“序列”对象区分开来

我有这样的功能

def print_stuff(items):
    if isinstance(items, (str, bytes)):
        items = (items,)
    for item in items:
        print (item)
Run Code Online (Sandbox Code Playgroud)

可以这样称呼:

In [37]: print_stuff(('a', 'b'))
a
b

In [38]: print_stuff('a')
a
Run Code Online (Sandbox Code Playgroud)

我不喜欢做,isinstance (items, (str, bytes))我更愿意做isinstance(item, (collections.abc.MAGIC))

其中MAGIC是所有序列对象的ABC,可以包含其他序列对象,例如

  • 元组
  • 清单
  • numpy.array
  • 一些用户定义的矢量类,等等

但不是:

  • 力量
  • 个字节
  • 一些用户定义的UTF-16的str类,等等

恐怕这是不可能的,tuple并且str具有相同的7个ABC :(

In [49]: [v for k, v in vars(collections.abc).items()
    ...:                                   if inspect.isclass(v) and issubclass(tuple, v) ]
Out[49]:
[collections.abc.Hashable,
 collections.abc.Iterable,
 collections.abc.Reversible,
 collections.abc.Sized,
 collections.abc.Container,
 collections.abc.Collection,
 collections.abc.Sequence]

In [50]: [v for k, v in …
Run Code Online (Sandbox Code Playgroud)

abc python-3.x

6
推荐指数
1
解决办法
548
查看次数

带有 ABC mixin 的 NamedTuple 类

我的问题如下:我想创建一个继承自typing.NamedTuple的类和另一个抽象类中的mixin。理想情况下我想做这样的事情:

from typing import *
from abc import ABC, abstractmethod

class M(ABC):
    @abstractmethod
    def m(self, it: Iterable[str]) -> str:
        pass

class N(NamedTuple, M):
    attr1: str

    def m(self, it):
        return self.attr1 + it
Run Code Online (Sandbox Code Playgroud)

当我现在尝试这样做时,我收到此错误:

TypeError: metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases
Run Code Online (Sandbox Code Playgroud)

我知道我可以这样做:

from typing import *
from abc import ABC, abstractmethod

class M(ABC):
    @abstractmethod
    def m(self, it: Iterable[str]) -> str:
        pass

class NT(NamedTuple):
    attr1: str

class N(NT, …
Run Code Online (Sandbox Code Playgroud)

python abc namedtuple python-3.6

6
推荐指数
1
解决办法
1172
查看次数

使用带有`abc`库的抽象类时获取python类名

我想在使用带有abc库的抽象类时提取 python 类名。不幸的是,我收到了 class name ABCMeta


import abc

class A(abc.ABC)
    pass

class B(A)
    pass

print(A.__class__.__name__)  # output: 'ABCMeta'
print(B.__class__.__name__)  # output: 'ABCMeta'
print(str(A))  # output: "<class '__main__.A'>"
print(str(B))  # output: "<class '__main__.B'>"

Run Code Online (Sandbox Code Playgroud)

我希望我应该收到如下输出

print(A.__class__.__name__)  # output: 'A'
print(B.__class__.__name__)  # output: 'B'
Run Code Online (Sandbox Code Playgroud)

str(A)str(B)似乎让我假设类的名字可以从什么地方提取打印的类名。但尽管如此,我对str用来解析和获取类名不感兴趣。

python abc

6
推荐指数
1
解决办法
1031
查看次数

即使类的所有方法都已实现,我是否可以将其标记为抽象类?

有没有办法将 python 类标记为抽象或不可实例化,即使它的所有抽象方法都已实现?

class Component(ABC):
    @abstractmethod
    def operation(self) -> None:
        pass

class Decorator(Component): # I would like this class to be abstract
    def operation(self) -> None:
        print("basic operation")
Run Code Online (Sandbox Code Playgroud)

我发现的唯一解决方法是在类中选择一些方法来同时具有实现和@abstractmethod装饰器,但是随后 python 需要子抽象类的派生者来重新实现该方法。

这也可以通过让子类调用来解决super(),但pylint抱怨这是一个无用的调用。

class Component(ABC):
    @abstractmethod
    def operation(self) -> None:
        pass

class Decorator(Component): # I would like this class to be abstract
    @abstractmethod
    def operation(self) -> None:
        print("basic operation")

class ConcreteDecorator(Decorator): 
    def operation(self) -> None: # python makes child class re-implement
        super().operation()  # pylint complains …
Run Code Online (Sandbox Code Playgroud)

python abstract-class abc

6
推荐指数
1
解决办法
378
查看次数