标签: abstract-base-class

issubclass的抽象基类Sequence

该列表显示了你需要实现你的类方法被"视为"为序列:__getitem__,__len__,__contains__,__iter__,__reversed__,index,和count.那么为什么这个最小的实现不起作用,为什么issubclass(S, Sequence) is False呢?

from collections import *


class S(object):
    def __getitem__(self, item):
        raise IndexError

    def __len__(self):
        return 0

    def __contains__(self, item):
        return False

    def __iter__(self):
        return iter(())

    def __reversed__(self):
        return self

    def index(self, item):
        raise IndexError

    def count(self, item):
        return 0


issubclass(S, Iterable)   # True  :-)
issubclass(S, Sized)      # True  :-)
issubclass(S, Container)  # True  :-)
issubclass(S, Sequence)   # False :-(
Run Code Online (Sandbox Code Playgroud)

我需要实现一个我忽略的额外方法吗?我是否误解了抽象基类?子类化当然 …

python duck-typing subclassing abstract-base-class isinstance

3
推荐指数
1
解决办法
533
查看次数

获取 ABCMeta 的所有已注册子类

我有一个类似于以下的目录结构:

\n\n
.\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 main.py\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 model.py\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 models\n    \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 __init__.py\n    \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 model_a.py\n    \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 model_b.py\n
Run Code Online (Sandbox Code Playgroud)\n\n

model.py包含一个抽象基类:

\n\n
from abc import ABCMeta, abstractmethod\n\nclass Base(metaclass=ABCMeta):\n\n    @abstractmethod\n    def run(self):\n        pass\n
Run Code Online (Sandbox Code Playgroud)\n\n

models文件夹中有该基类的两个实现,model_a.pymodel_b.py,它们将自己注册到主Base类。 model_a.py看起来像这样:

\n\n
from model import Base\n\nclass ModelA(Base):\n\n    def run(self):\n        return "a"\n\nModelA.register(Base)\n\nassert issubclass(ModelA, Base)\n
Run Code Online (Sandbox Code Playgroud)\n\n

并且model_b.py是相似的。

\n\n

现在,我想做的main.py是创建一个包含所有子类的字典Base,以便我可以选择一个子类(通过程序的 GUI)并运行它:

\n\n
from model import Base\n\nsubclasses = Base.__subclasses__()\n\ndct = {cls.__name__: cls for cls in subclasses}\n\nklass = dct[\'ModelA\']\nklass.run()\n
Run Code Online (Sandbox Code Playgroud)\n\n

但我无法让它工作。RuntimeError: …

subclass abstract-base-class python-3.x

3
推荐指数
1
解决办法
1333
查看次数

在显式子类型构造期间未调用typing.Protocol 类`__init__` 方法

Python 的PEP 544引入typing.Protocol了结构子类型,也就是“静态鸭子类型”。

在此 PEP 关于合并和扩展协议的部分中,指出

一般的哲学是协议大多像常规的 ABC,但静态类型检查器会专门处理它们。

因此,人们期望从 的子类继承与期望从 的子类继承typing.Protocol的方式大致相同abc.ABC

from abc import ABC
from typing import Protocol

class AbstractBase(ABC):
    def method(self):
        print("AbstractBase.method called")

class Concrete1(AbstractBase):
    ...

c1 = Concrete1()
c1.method()  # prints "AbstractBase.method called"

class ProtocolBase(Protocol):
    def method(self):
        print("ProtocolBase.method called")

class Concrete2(ProtocolBase):
    ...

c2 = Concrete2()
c2.method()  # prints "ProtocolBase.method called"
Run Code Online (Sandbox Code Playgroud)

正如所料,具体子类Concrete1Concrete2继承method从他们各自的超类。此行为记录在PEP的显式声明实现部分:

要明确声明某个类实现了给定的协议,可以将其用作常规基类。在这种情况下,类可以使用协议成员的默认实现。

...

请注意,显式和隐式子类型之间几乎没有区别,显式子类化的主要好处是“免费”获得一些协议方法。

然而,当协议类实现__init__的方法,__init__是 …

protocols abstract-base-class python-3.x python-typing

3
推荐指数
1
解决办法
418
查看次数

当从抽象基类继承时,为什么__slots__在Python 2和3中表现不同

我创建了以下类,以一种以内存效率的方式在平面上存储可变点 - 我需要一个可变的等价物namedtuple('Point', 'x y').由于实例字典很大,我想我会选择__slots__:

from collections import Sequence

class Point(Sequence):
    __slots__ = ('x', 'y')

    def __init__(self, x=0, y=0):
        self.x = x
        self.y = y

    def __getitem__(self, item):
        return getattr(self, self.__slots__[item])

    def __setitem__(self, item, value):
        return setattr(self, self.__slots__[item], value)

    def __repr__(self):
        return 'Point(x=%r, y=%r)' % (self.x, self.y)

    def __len__(self):
        return 2
Run Code Online (Sandbox Code Playgroud)

在Python 3上测试时,一切似乎都没问题:

>>> pt = Point(12, 42)
>>> pt[0], pt.y
(12, 42)
>>> pt.x = 5
>>> pt
Point(x=5, y=42)
>>> pt.z = 6
Traceback …
Run Code Online (Sandbox Code Playgroud)

python python-2.x abstract-base-class python-3.x

2
推荐指数
1
解决办法
446
查看次数

C++"使用抽象基类调用纯虚方法"

我使用的是一个只有纯虚方法的抽象基类,在C++中有一个接口行为(是的,我来自Java).就我的研究而言,这似乎是要走的路.

我必须抽象基类,GraphReader和Graph.

class Graph{
   public:
   Graph() {};
   virtual ~Graph() {};
   virtual void layout() = 0;
   virtual std::vector<std::shared_ptr<Node>> getNodes() = 0;
   virtual std::vector<std::shared_ptr<Edge>> getEdges() = 0;

   protected:

};

class GraphReader{
   public:
   GraphReader(std::string fileName_) :
         fileName(fileName_) {};
   virtual ~GraphReader() {};
   virtual Graph* read() = 0;

   protected:
   std::string fileName;
};
Run Code Online (Sandbox Code Playgroud)

这两个都有从GraphReader/Graph继承的派生类.

class OgdfGraph : public Graph{
   public:
   OgdfGraph();
   virtual ~OgdfGraph();
   void setOgdfGraph(ogdf::Graph &oGraph);
   std::vector<std::shared_ptr<Node>> getNodes();
   std::vector<std::shared_ptr<Edge>> getEdges();
   void layout();

   private:
   [...]

};

class OgdfGmlReader : public GraphReader {  
   public:
   OgdfGmlReader(std::string fileName);
   virtual ~OgdfGmlReader(); …
Run Code Online (Sandbox Code Playgroud)

c++ inheritance abstract-class abstract-base-class

2
推荐指数
1
解决办法
525
查看次数

C++:如果类没有成员函数,如何创建抽象基类?

我有一个抽象的基类,它的目的是允许创建一个指向基类的指针数组.(对'很多东西'有用......)

我的抽象基类不包含任何成员函数.因此没有纯虚方法,因此我猜它在技术上并不是抽象的.

但是,我不希望能够创建此类的实例.

是否可以创建无成员抽象基类?如果没有,是否有另一种解决方案来阻止我的"抽象基础"的实例被创建?是否会使构造函数protected足够?

有人向我指出,实际上,如果该类的目的是允许创建指向基类的指针的向量或数组,则不需要抽象基类 - 可能根本就没有基类和使用继承层次结构顶部的类作为基类.或者,可以复制并粘贴该顶级类并交换实现的纯虚函数方法而不实现,但是这在逻辑上与抽象基指针的想法不一致,并且会导致更难以维护代码.

c++ abstract-base-class

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

指向基类的指针数组:如何调用唯一的派生类方法

谷歌搜索了一下这一个,但似乎无法找到一个明确的答案.

如何在以下示例中调用unscramble()方法?

谢谢.:^)

class Food {
public:
    Food(string _t):type(_t);
    virtual void eat() = 0;
private:
    string type;
}

class Fruit : public Food {
public:
    Fruit(string _t):Food(_t) {
    virtual void eat() { // Yummy.. }
}   

class Egg : public Food {
public:
    Egg(string _t):Food(_t)};
    virtual void eat() { // Delicious! };
    void unscramble();
}     

int main() {
    Food *ptr[2];
    ptr[0] = new Fruit("Apple");
    ptr[1] = new Egg("Brown");

    // Now, I want to call the unscramble() method on Egg.
    // …
Run Code Online (Sandbox Code Playgroud)

c++ class derived-class abstract-base-class c++11

0
推荐指数
1
解决办法
67
查看次数

为什么__sub__和__rsub__实现了,以这种方式,对于numbers.Complex

我一直在寻找的实施Complexnumbers模块,发现__sub____rsub__看起来像这样的实现:

def __sub__(self, other):
    """ self - other """
    return self + -other

def __rsub__(self, other):
    """ other - self """
    return -self + other
Run Code Online (Sandbox Code Playgroud)

这困惑了我.

首先,我不确定为什么要实现这些(猜测所有子类都Complex可以回退它?),其次,我无法理解为什么他们选择使用这样的一元-来实现它.

有任何想法吗?

python numbers class abstract-base-class

0
推荐指数
1
解决办法
622
查看次数