简体   繁体   English

Python 检查继承摘要中的属性类型 class

[英]Python check attribute type in inherited abstract class

I have a basic abstract class structure such as the following:我有一个基本的抽象 class 结构,如下所示:

from abc import ABCMeta, abstractmethod

class BaseClass(metaclass=ABCMeta):
   @property
   @abstractmethod
   def class_name(self):
       pass

   @property
   @abstractmethod
   def class_val(self):
       pass

   @abstractmethod
   def foo(self):
       pass

   def bar(self):
       # do something


class ChildClass1(BaseClass):
    class_name = "Child1"
    class_val = 1

    def foo(self):
        # do something else


class ChildClass2(BaseClass):
    class_name = "Child2"
    class_val = 2

    def foo(self):
        # do something else again

This works to basically do what I want, ie, it lets me define variations of a base class which share the same implementation of the method bar() but have different implementations of foo() , with different class-specific attributes -- all of which must be implemented in the child classes, otherwise it raises the error TypeError: Can't instantiate abstract class ChildClass1 with abstract methods class_name (for example, if I try implement it without the class_name class attribute).这基本上可以做我想做的事,即,它让我定义一个基类 class 的变体,它们共享方法bar()的相同实现,但具有不同的foo()实现,具有不同的类特定属性——所有必须在子类中实现,否则会引发错误TypeError: Can't instantiate abstract class ChildClass1 with abstract methods class_name (例如,如果我尝试在没有class_name class 属性的情况下实现它)。

This is almost what I want.这几乎就是我想要的。 However I would like to know if there is any way I can force the child classes to have a string type for the class_name attribute, an int type for the class_val attribute, etc.?但是我想知道是否有任何方法可以强制子类的class_name属性具有字符串类型, class_val属性具有int类型等?

The best thing to do would be to use type hints , and then validate the type hints using a third party tool such as mypy :最好的办法是使用类型提示,然后使用第三方工具(如mypy )验证类型提示:

class BaseClass(metaclass=ABCMeta):
   @property
   @abstractmethod
   def class_name(self) -> str:
       pass

   @property
   @abstractmethod
   def class_val(self) -> int:
       pass

   @abstractmethod
   def foo(self):
       pass

   def bar(self):
       pass

If you try to define a subclass with the wrong types for the properties, mypy will throw an error, eg with:如果您尝试为属性定义错误类型的子类, mypy将抛出错误,例如:

class ChildClass2(BaseClass):
    class_name = "Child2"
    class_val = "a"

    def foo(self):
        pass

you'd get the error along the lines of:你会得到如下错误:

test.py: error: Incompatible types in assignment
(expression has type "str", base class "BaseClass" defined the type as "int")

This technically doesn't stop someone from defining a subclass that has the wrong type, since the Python runtime ignores type hints.这在技术上不会阻止某人定义具有错误类型的子类,因为 Python 运行时会忽略类型提示。 However, an approach that raises an error if a bad type is encountered would likely need a call to isinstance() for each instance variable, which would become unwieldy if you have a lot of properties that you want to enforce the types for.但是,如果遇到错误类型则引发错误的方法可能需要为每个实例变量调用isinstance() ,如果您有许多要为其强制执行类型的属性,这将变得笨拙。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM