- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我想为作为参数传递的 Python 类型正确添加类型。例如。让我们假设我们想向以下函数添加类型:
def do_something_based_on_types(
...
type_name: str,
str_to_type_mapping: Dict[str, Any], # what instead of Any?
):
...
object = str_to_type_mapping[type_name]()
...
我们想要传递来自 str
的映射。键入基于我们想要构造所选类的对象的类型。对于这种情况,正确的键入是什么(而不是代码示例中使用的 Any
)。
最佳答案
你的例子非常动态。由于 Python 类型注释的主要目的是支持静态分析,因此它们可以为我们提供的功能是有限的。不过,我确实认为我们可以做得比 Any
更好。 !
(注意:为了防止混淆,我会将代码片段中名为 object
的变量称为 my_object
,当我使用 object
时,我指的是 Python 类型)。
由于您提到提供的字典中的值应该是可以启动的类型,因此合理的类型注释可以是 Dict[str, Type[object]]
或Dict[str, Type]
,其中后者相当于 Dict[str, Type[Any]]
。第一个是最严格的,它将限制类型检查器允许您在 my_object
上执行的操作。多变的。第二个仅比普通的 Any
稍好一些。 ,尽管当调用者意外提供实例而不是类型时,它会警告调用者。
根据您提供的代码片段,使用字典值的唯一方法是创建一个新实例。类型并不是唯一可以做到这一点的东西。实际上,任何采用零参数并返回对象的可调用函数(普通函数、类方法)也足够了。所以使用Callable[[], object]
将为函数的调用者提供更大的灵活性,并且在传递不具有零参数构造函数的类型时发出警告。我更喜欢这个而不是 Type
因为它看起来更安全,也更符合 Python 鸭子类型的精神。
这两种解决方案都有一个限制,即在您的函数内部,我们对 my_object
的类型一无所知。 。在一般情况下,我们“被迫”做isinstance
每次我们执行对象类型不支持的操作时都会进行检查。但是,也许在您的用例中,单个字典不应该只包含任何类型。可能是这样的:
MyBase
.对于情况(1),我们可以替换 object
输入类型 MyBase
。类型检查器应该能够执行 MyBase
支持的操作使用安全,并在提供的字典包含其他类型时发出警告。
对于情况 (2), typing.Protocol
可以帮助我们。您可以使用所需的操作定义自定义协议(protocol),并将其添加到类型注释中:
class MyCustomProto(Protocol):
foo: int
def bar(self) -> str: ...
现在类型检查器应该知道 my_object
应该具有整数属性 foo
和一个方法bar
返回一个字符串。请注意Protocol
已添加到 Python 3.8,并且可通过 typing-extensions 适用于以前的版本包。
与你的问题没有直接关系,但如果你只使用字典阅读,你应该考虑替换 Dict
与 Mapping
类型。这允许调用者提供除 dict 子类之外的任何映射类型(实际上不太可能发生)。但更重要的是,它会在意外修改提供的映射时向您发出警告,这可能会导致难以发现错误。因此,我的最终建议是 Mapping[str, Callable[[], <X>]
,与 <X>
是 object
之一, MyCustomProto
或MyBase
.
关于python - 如何为类型参数设置 python 类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60343591/
我是一名优秀的程序员,十分优秀!