描述符的类型提示是什么?

问题描述 投票:0回答:1

这是一个与如何在不使用字符串的情况下将namedtuple属性传递给方法?相关的新问题。 我如何在方法

column
中输入提示
attempt_access
参数。它可以是
int
或命名元组的属性。


from typing import NamedTuple


class Record(NamedTuple):
    id: int
    name: str
    age: int


class NamedTupleList:

    def __init__(self, data):
        self._data = data

    def attempt_access(self, row: int, column) -> any:
        r = self._data[row]
        try:
            val = r[column]
        except TypeError:
            val = column.__get__(r)
        return val

data = [Record(1, 'Bob', 30),
        Record(2, 'Carol', 25),
        Record(3, 'Ted', 29),
        Record(4, 'Alice', 28),
        ]
class_data = NamedTupleList(data)

print('attempt_access by index')
v = class_data.attempt_access(0, 2)
print(v)

print('attempt_access by name')
v = class_data.attempt_access(0, Record.age)
print(v)
python python-typing
1个回答
0
投票

这应该可以安抚我的心:

import typing

class RecordProtocol(typing.Protocol):
    def __get__(self, instance: 'Record', owner: typing.Type['Record']) -> int | str:
        ...

class Record(typing.NamedTuple):
    id: int
    name: str
    age: int

class NamedTupleList:
    def __init__(self, data: list[Record]):
        self._data = data

    def attempt_access(self, row: int, column: int | RecordProtocol) -> int | str:
        r = self._data[row]
        if isinstance(column, int):
            return r[column]
        else:
            return column.__get__(r, Record)

data = [
    Record(1, "Bob", 30),
    Record(2, "Carol", 25),
    Record(3, "Ted", 29),
    Record(4, "Alice", 28),
]
class_data = NamedTupleList(data)
print(class_data.attempt_access(0, 2))
print(class_data.attempt_access(0, Record.age))

一些注意事项:

  • 原始代码的
    try
    /
    except
    是老式的鸭子打字风格的Python代码。这对于静态类型检查器并不友好,因为静态类型检查器更喜欢条件分支。
  • 我只实现了您的具体示例所需的最小接口。通用 Python 描述符协议的功能更齐全的类型提示可以在这个答案中找到。
© www.soinside.com 2019 - 2024. All rights reserved.