Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何处理内部类属性依赖关系?_Python_List - Fatal编程技术网

Python 如何处理内部类属性依赖关系?

Python 如何处理内部类属性依赖关系?,python,list,Python,List,如果您想在更改属性时更改类中的其他变量,只需为其编写一个属性即可。如果您有一个简单的数据类型,那么这很好。但是,如果您的变量包含一个复杂的类型,如列表(不是那么不典型),则可以更改内容本身,而无需再次调用变量.setter 是否有任何回调或事件可用于跟踪对类的列表属性的更改?还可以做些什么来保持代码干净,而不破坏类的内部功能 例如: class Accumulator(object) def __init__(self,all_things): # :param all_thing

如果您想在更改属性时更改类
中的其他变量,只需为其编写一个
属性即可。如果您有一个简单的数据类型,那么这很好。但是,如果您的变量包含一个复杂的类型,如列表(不是那么不典型),则可以更改内容本身,而无需再次调用
变量.setter

是否有任何回调或事件可用于跟踪对类的列表属性的更改?还可以做些什么来保持代码干净,而不破坏类的内部功能

例如:

class Accumulator(object)
  def __init__(self,all_things):
     # :param all_things: a list of stuff of any kind
     self.__all_things = all_things
  @property
  def all_things(self):
     return self.__all_things
  @all_things.setter
  def all_things(self,input):
      self.__all_things = input

跳出框框思考可能是解决办法。首要任务不是让类结构保持活动状态,而是找到一个可以工作并允许干净API的模式

您必须使用list的自定义子类来检测更改:

class MyList(list):
    on_change_callback = None

    def _notify(self):
        if self.on_change_callback is not None:
            self.on_change_callback(self)

    def __setitem__(self, index, value):
        super(MyList, self).__setitem__(self, index, value)
        self._notify()

    # Etc, each mutating method needs to be overridden.

您需要覆盖每个变异方法,调用原始方法(通过
super()
),然后调用
self.\u notify()
。有关方法列表,请参见章节。

为了便于讨论和提高创造力,我想自己提供以下解决方案:

class Accumulator(object):

    def __init__(self,all_things):
       #:param all_things: a sequence or generator of stuff of any kind
       self.__all_things = tuple(all_things)

    @property
    def all_things(self):
        return self.__all_things

    @property
    def all_things(self, all_things):
        self.__all_things = tuple(all_things)

它是干净的,只读的,不会出错或被滥用。现在同样的假设适用于问题的结构:如果你想改变它,你需要重置它。但你不必告诉用户,因为这是他唯一的机会。如果用户仍然想知道为什么,他可以阅读希望详细的类docstring。

简短回答:不使用自定义类替换列表,这是一个可能的解决方案。你能告诉我怎么做吗?在你写答案的时候,我做了一些研究。子类化(或者合成,如果你更喜欢的话)看起来都像是一个简单的过程。在你完成并假定没有bug之后,你仍然有一个比标准列表慢得多的对象(它可能是优化的C代码)。@erikb85:但这是你的选择;或者事实上,完全不允许对项目进行变异。在这种情况下,也许你是对的。我认为还是有更好的解决办法,就是不要像我那样写这门课。否则很多人会遇到这个问题,并且会有众所周知的标准解决方案,这些解决方案并不难实现<代码>应该有一种——最好只有一种——显而易见的方法来实现它。虽然这种方式一开始可能并不明显,除非你是荷兰人。
-Zen of PythonTotally脱离了主题,但请记住:我是荷兰人。;-)另外:pythonic的方法是不担心这些类型的突变,除非有一个令人信服的方法这样做。例如,ZODB持久化模块确实关心(因此它可以将更改提交到数据库),并为您提供跟踪它们的工具(列表和映射的自定义类)。至于性能:列表突变本身仍然以原始的
list
类型处理(因此在C中)。Python只处理通知,而瓶颈将在回调本身,而不是调用它。我认为你把重点放在了错误的问题上。