Python OOP,方法/类中参数的类型验证

标签 python python-3.x oop types

我试图理解 Python 中的 OOP,但我遇到了“非 Python 思维方式”的问题。我想为我的类提供一个方法来验证参数的类型并在参数类型不正确时引发异常(例如 ValueError)。我得到的最接近我的愿望的是:

class Tee(object):
    def __init__(self):
        self.x = 0
    def copy(self, Q : '__main__.Tee'):
        self.x = Q.x
    def __str__(self):
        return str(self.x)

a = Tee()
b = Tee()
print(type(a))  # <class '__main__.Tee'>
print(isinstance(a, Tee))  # True
b.x = 255
a.copy(b)
print(a)        # 255
a.copy('abc')   # Traceback (most recent call last): [...]
                # AttributeError: 'str' object has no attribute 'x'

因此,即使我试图确保我的 copy 方法中的参数 Q 的类型属于同一类,解释器也只是通过它并引发当它试图从字符串中获取 x 成员时出现 AttributeError

我知道我可以做这样的事情:

[...]
    def copy(self, Q):
        if isinstance(Q, Tee):
            self.x = Q.x
        else:
            raise ValueError("Trying to copy from a non-Tee object")
[...]
a = Tee()
a.copy('abc')   # Traceback (most recent call last): [...]
                # ValueError: Trying to copy from a non-Tee object

但是围绕类到处实现听起来工作量很大,即使我做了一个专门的函数、方法或装饰器。所以,我的问题是:对此是否有更“pythonic”的方法

顺便说一下,我使用的是 Python 3.6.5。

最佳答案

在运行时不强制执行类型注释。时期。它们目前仅供 IDE 或静态分析器使用,如 mypy ,或通过您自己编写的任何反省这些注释的代码。但由于 Python 主要基于 duck typing ,运行时不会也不会实际强制执行类型。

如果您在开发期间使用静态类型检查器来捕获此类错误,这通常就足够了。如果你想进行实际的运行时检查,你可以使用 assertions :

assert isinstance(Q, Tee), f'Expected instance of Tee, got {type(Q)}'

但它们也主要用于调试,因为可以关闭断言。要拥有强类型断言,您需要明确:

if not isinstance(Q, Tee):
    raise TypeError(f'Expected instance of Tee, got {type(Q)}')

但同样,这可以防止鸭子打字,这并不总是可取的。

顺便说一句,你的类型注释应该只是 def copy(self, Q: 'Tee'),不要包括 '__main__';另见 https://docs.python.org/3/whatsnew/3.7.html#whatsnew37-pep563 .

关于Python OOP,方法/类中参数的类型验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52741293/

相关文章:

Python:每秒运行循环并触发函数5秒

arrays - 如何复制字节数组

python-3.x - Pygame 没有移动我在屏幕上绘制的矩形

javascript - 从 JavaScript OOP 中的经典事件管理转向事件委托(delegate)

inheritance - 我应该继承 List<T> 还是将其作为属性?

python - 如何检查列表中是否出现两个列表项的任意组合

python - 从python列表迭代插入MySQL表

python - Python 中的 Google App Engine 文件夹 url

python - 删除和更换打印项目

c++ - C++中的继承语法