我正在try 创建一个类来表示已命名的二元组列表,但我在按名称访问元素时遇到了麻烦.这里有一个例子:

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, column):
        print(f'{self._data[row].age=}')
        r = self._data[row]
        print(f'{type(column)=}')
        print(f'{column=}')
        print(f'{r[column]=}')

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

print('show data')
print(f'{data[0]=}')
print(f'{type(data[0])=}')
print(f'{data[0].age=}')

print('\nshow class_data')
print(f'{type(class_data)=}')

print('\nattempt_access by index')
class_data.attempt_access(0, 2)

print('\nattempt_access by name')
class_data.attempt_access(0, Record.age)  # why can't I do this?

制作:

data[0]=Record(id=1, name='Bob', age=30)
type(data[0])=<class '__main__.Record'>
data[0].age=30

show class_data
type(class_data)=<class '__main__.NamedTupleList'>

attempt_access by index
self._data[row].age=30
type(column)=<class 'int'>
column=2
r[column]=30

attempt_access by name
self._data[row].age=30
type(column)=<class '_collections._tuplegetter'>
column=_tuplegetter(2, 'Alias for field number 2')

    print(f'{r[column]=}')
             ~^^^^^^^^
TypeError: tuple indices must be integers or slices, not _collections._tuplegetter

因此,我可以通过索引成功访问"行"和"列",但如果我想通过方法调用访问列(即namedtuple属性),我会收到错误.有趣的是,列值是_tuplegetter(2, 'Alias for field number 2'),所以我的方法中已知索引,但我无法访问它.有人知道如何访问此值以便向方法传递名称吗?我试图避免将名称作为字符串传递-我真的很想利用命名空间,因为这毕竟是命名体的优势之一.

推荐答案

有趣的问题.该字段是descriptor,因此您可以调用它:

class NamedTupleList:

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

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

演示 :

>>> class_data.attempt_access(0, 2)
30
>>> class_data.attempt_access(0, Record.age)
30

Python相关问答推荐

Python:如何定义类型注释,以便生成的对象具有同名的属性和键?

如何输入提示抽象方法属性并让mypy高兴?

带有Postgres的Flask-Data在调用少量API后崩溃

Django关于UniqueBindition的更新

从包含基本数据描述的文本字段中识别和检索特定字符序列

Python中的锁定类和线程以实现dict移动

Flask主机持续 bootstrap 本地IP| Python

Ibis中是否有一个ANY或ANY_UTE表达,可以让我比较子查询返回的一组值中的值?

Polars -转换为PL后无法计算熵.列表

给定数据点,制定它们的关系

请从Python访问kivy子部件的功能需要帮助

在应用循环中间保存pandas DataFrame

Python中MongoDB的BSON时间戳

类型错误:输入类型不支持ufuncisnan-在执行Mann-Whitney U测试时[SOLVED]

如何在Windows上用Python提取名称中带有逗号的文件?

我如何根据前一个连续数字改变一串数字?

driver. find_element无法通过class_name找到元素'""

多指标不同顺序串联大Pandas 模型

处理具有多个独立头的CSV文件

寻找Regex模式返回与我当前函数类似的结果