首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何将参数传递给Python3中的自定义静态类型提示?

如何将参数传递给Python3中的自定义静态类型提示?
EN

Stack Overflow用户
提问于 2018-09-04 01:05:13
回答 1查看 1.3K关注 0票数 5

我是Python3中静态类型提示的铁杆粉丝和倡导者,我已经使用它们一段时间了,没有遇到任何问题。

我刚刚遇到了一个新的边缘情况,我似乎不能编译。如果我想定义一个自定义类型,然后定义它的参数,该怎么办?

例如,这在Python 3中很常见:

代码语言:javascript
复制
from typing import List, NewType
CustomObject = NewType('CustomObject', List[int])

def f(data: List[CustomObject]):
    # do something

但这不会编译:

代码语言:javascript
复制
class MyContainer():
    # some class definition ...

from typing import NewType
SpecialContainer = NewType('SpecialContainer', MyContainer)

def f(data: SpecialContainer[str]):
    # do something

我意识到在这种情况下,从技术上讲,SpecialContainer是一个函数,但它不应该作为类型签名上下文中的函数来计算。第二个代码片段因TypeError: 'function' object is not subscriptable而失败。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-09-04 01:44:44

编译我的代码示例

你必须从头开始设计你的类来接受静态类型提示。这不符合我最初的用例,因为我试图声明第三方类的特殊子类型,但它编译了我的代码样本。

代码语言:javascript
复制
from typing import Generic, TypeVar, Sequence, List

# Declare your own accepted types for your container, required
T = TypeVar('T', int, str, float)

# The custom container has be designed to accept types hints
class MyContainer(Sequence[T]):
    # some class definition ...

# Now, you can make a special container type
# Note that Sequence is a generic of List, and T is a generic of str, as defined above
SpecialContainer = TypeVar('SpecialContainer', MyContainer[List[str]])

# And this compiles
def f(data: SpecialContainer):
    # do something

子类型化第三方类

我的初衷是创建一个类型提示,用于解释函数f()如何接受一个pd.DataFrame对象,该对象由整数索引,并且其单元格都是字符串。使用上面的答案,我想出了一个人为的方式来表达这一点。

代码语言:javascript
复制
from typing import Mapping, TypeVar, NewType, NamedTuple
from pandas import pd

# Create custom types, required even if redundant
Index = TypeVar('Index')
Row = TypeVar('Row')

# Create a child class of pd.DataFrame that includes a type signature
# Note that Mapping is a generic for a key-value store
class pdDataFrame(pd.DataFrame, Mapping[Index, Row]):
    pass

# Now, this compiles, and explains what my special pd.DataFrame does
pdStringDataFrame = NewType('pdDataFrame', pdDataFrame[int, NamedTuple[str]])

# And this compiles
def f(data: pdStringDataFrame):
    pass

这值得吗?

  • 如果您正在编写一个类似于容器泛型的自定义类,如SequenceMappingAny,那么请使用它。您可以自由地将类型变量添加到您的类definition.
  • If中,以表示没有实现类型提示的第三方类的特定用法:

代码语言:javascript
复制
- Try using an existing type variable to get your point across, e.g. `MyOrderedDictType = NewType('MyOrderedDictType', Dict[str, float])`
- If that doesn't work, you'll have to clutter your namespace with trivial child classes and type variables to get the type hint to compile. Better to use a docstring or comment to explain your situation.

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52153879

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档