如何在python中实现引用列表? [英] How to implement a list of references in python?

查看:222
本文介绍了如何在python中实现引用列表?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在 python (2) 中对对象集合进行建模.集合应该通过列表接口使对象的某个属性(整数、浮点数或任何不可变对象)可用.

(1)

<预><代码>>>>打印(collection.attrs)[1, 5, 3]>>>collection.attrs = [4, 2, 3]>>>打印(object0.attr == 4)真的

我特别希望集合中的这个列表接口允许重新分配单个对象的属性,例如

(2)

<预><代码>>>>集合.属性[2] = 8>>>打印(object2.attr == 8)真的

我确信这是一个经常发生的情况,不幸的是我无法找到一个令人满意的答案,说明如何在 stackoverflow/google 等上实现它.

在幕后,我希望将 object.attr 实现为可变对象.不知何故,我还希望集合保存对 object.attr 的引用列表",而不是分别引用的(不可变的)值本身.

我想请教您如何以优雅灵活的方式解决这个问题.

允许(1)但不允许(2)的可能实现是

class 组件(对象):"""众多组件之一."""def __init__(self, attr):self.attr = attr类系统(对象):"""一个 System object 包含并管理许多 Component 实例.系统是调整组件的主要界面."""def __init__(self, attr_list):self._components = []对于 attr_list 中的 attr:新 = 组件(属性)self._components.append(new)@财产定义属性(自我):#!!!这打破(2):返回 [component.attr for self._components 中的组件]@attrs.setterdef attrs(self, new_attrs):对于组件,zip 中的 new_attr(self._components, new_attrs):component.attr = new_attr

该!!!换行符 (2) 因为我们创建了一个新列表,其条目是对所有 Component.attr 值的引用,而不是对属性本身的引用.

感谢您的投入.

圣诞节

解决方案

只需在中间添加另一个代理:

class _ListProxy:def __init__(self, system):self._system = 系统def __getitem__(self, index):返回 self._system._components[index].attrdef __setitem__(self, index, value):self._system._components[index].attr = 值类系统:...@财产定义属性(自我):返回 _ListProxy(self)

您可以通过实现所有其他 list 方法来使代理更漂亮,但这对于您的用例来说已经足够了.

I'm trying to model a collection of objects in python (2). The collection should make a certain attribute (an integer, float or any immutable object) of the objects available via a list interface.

(1)

>>> print (collection.attrs)
[1, 5, 3]
>>> collection.attrs = [4, 2, 3]
>>> print (object0.attr == 4)
True

I especially expect this list interface in the collection to allow for reassigning a single object's attribute, e.g.

(2)

>>> collection.attrs[2] = 8
>>> print (object2.attr == 8)
True

I am sure this is a quite frequently occurring situation, unfortunately I was not able to find a satisfying answer on how to implement it on stackoverflow / google etc.

Behind the scenes, I expect the object.attr to be implemented as a mutable object. Somehow I also expect the collection to hold a "list of references" to the object.attr and not the respectively referenced (immutable) values themselves.

I ask for your suggestion how to solve this in an elegant and flexible way.

A possible implementation that allows for (1) but not for (2) is

class Component(object):
    """One of many components."""
    def __init__(self, attr):
        self.attr = attr

class System(object):
    """One System object contains and manages many Component instances.
    System is the main interface to adjusting the components.
    """
    def __init__(self, attr_list):
        self._components = []
        for attr in attr_list:
            new = Component(attr)
            self._components.append(new)

    @property
    def attrs(self):
        # !!! this breaks (2):
        return [component.attr for component in self._components] 
    @attrs.setter
    def attrs(self, new_attrs):
        for component, new_attr in zip(self._components, new_attrs):
            component.attr = new_attr

The !!! line breaks (2) because we create a new list whose entries are references to the values of all Component.attr and not references to the attributes themselves.

Thanks for your input.

TheXMA

解决方案

Just add another proxy inbetween:

class _ListProxy:
    def __init__(self, system):
        self._system = system

    def __getitem__(self, index):
        return self._system._components[index].attr

    def __setitem__(self, index, value):
        self._system._components[index].attr = value


class System:
    ...
    @property
    def attrs(self):
        return _ListProxy(self)

You can make the proxy fancier by implementing all the other list methods, but this is enough for your use-case.

这篇关于如何在python中实现引用列表?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆