0

我正在尝试创建一个处理程序,该处理程序在任何对象的属性值发生变化时触发。我对python还是很陌生,并没有真正想出任何工作方法。这就是我所做的,我知道它不能像这样工作,这只是为了展示我想要实现的目标:

# ../handler.py
import copy

class Handler:
    def __init__(self, obj):
        # Let the object know it's handler
        obj.handler = self

        # Copy the object
        self.copy = copy.deepcopy(obj)

        # Let handler know it's object
        self.obj = obj

        # Handler not running atm.
        self.running = False

def start(self):
    # Running
    self.running = True

    # As long as running...
    while self.running:

        # Loop through all objects attributes
        for attr in self.obj.__dict__:

            # If attribute's value has changed
            if self.copy.__dict__[attr] != self.obj.__dict__[attr]:

                # Print out a message
                print("%s was changed to %s" %(attr, self.obj.__dict__[attr]))

                # Update the value to our copy
                self.copy.__dict__[attr] = self.obj.__dict__[attr]

def stop(self):
    # Not running
    self.running = False

这是主文件

# ../main.py
from handler import Handler

class Value:
    def __init__(self, v=None):
        self.value = v

def createObject(v):
    obj = Value(v)
    Handler(obj)
    return obj

myObj = createObject(5)
myObj.handler.start()

但是,这将导致此文本被打印出来:handler was changed to <Handler.Handler object at 0x0000000002B1FC50>但我没有在这里更改处理程序?此外,由于 Handler.start() 函数中的 while 循环,程序将冻结……我怎样才能以一种有效的方式实现它?

4

2 回答 2

1
class Proxier(object):
    def __init__(self, obj):
        self.obj = obj
        obj.handler = self

    def __getattr__(self, key):
        return getattr(self.obj, key)

    def __setattr__(self, key, value):
        if key != 'obj':
            oldvalue = getattr(self.obj, key)
            if oldvalue != value:
                doSomething()

            setattr(self.obj, key, value)
        else:
            setattr(self, key, value)

class Value(object):
    def __init__(self, v=None):
        self.value = v

myObj = Proxier(Value(2))
于 2012-11-03T18:41:20.930 回答
1

你实际上想要一个代理,这是一个开始......

class Proxy(object):
    def __init__(self, obj):
        object.__setattr__(self, '__obj', obj)
    def __getattribute__(self, name):
        return getattr(object.__getattribute__(self, '__obj'), name)


a = range(10)
p = Proxy(a)

p.append(10) # etc...

您还需要寻找__setattribute____delattribute__其他魔术方法...

当属性更改时,您将如何满足可能会有点棘手 - 因为您必须知道是否存在方法调用,从而就地更改了对象......(例如append上面)

一个快速的谷歌提出:http ://code.activestate.com/recipes/496741-object-proxying/

于 2012-11-03T18:44:14.377 回答