首页 > 解决方案 > Python:通过引用将类成员项传递给其成员函数之一

问题描述

我在一个类中有一些对类成员进行操作的函数。除了它们操作的类成员之外,这些函数几乎相同。为了避免不得不一遍又一遍地键入函数,只更改被更改的类成员,我创建了一个函数,其中一个参数是要更改的类成员。

这是一个非常简化的版本:

class Foo:
    a = 0
    b = 0

    def __set_member(self, member, value):
        member = value

    def set_a(self, value):
        self.__set_member(self.a, value)

f = Foo()

print(f.a)
f.set_a(2)
print(f.a)

但这输出:

0
0

在 C++ 中,这可以通过以下方式完成:

class Foo {

    void set_member(int& member, int value) {
        member = value;
    }

public:
    int a = 0;
    int b = 0;

    void set_a(int value) {
        set_member(this->a, value);
    }
};

显然我给出的例子不需要这个set_member函数,因为它很简单。

在我的实际代码中,setter 看起来像这样:

def requestOpenDoor1(self):
    # Non blocking function: sets door1 to `Opening` and then after 2 seconds sets it to `Open`
    self.__door1 = DoorStates.Opening
    async def callback(): self.__door1 = DoorStates.Open
    self.__tasks.append(AsyncTimer(2, callback))

一种方法是将该函数复制粘贴 20 次左右,然后只更改正在修改的类成员、转换状态、时间和 endState,但我宁愿减少代码重复。

我也尝试使用装饰器来解决这个问题:

class request_function_decorator(object):
    def __init__(self, tasks, stateToChange, transitionState, time, endState):
        self.__tasks = tasks
        self.__stateToChange = stateToChange
        self.__transitionState = transitionState
        self.__time = time
        self.__endState = endState
    def __call__(self, function):
        def wrapped_f(*args):
            self.__stateToChange = self.__transitionState
            async def callback(): self.__stateToChange = self.__endState
            self.__tasks.append(AsyncTimer(self.__time, callback))
        return wrapped_f

@request_function_decorator(__tasks, __door1, States.Opening, 2, States.Open)
def requestOpenDoor1(self):
    pass

但这也行不通。

怎样才能泛化这个函数来减少代码重复呢?

谢谢。

标签: pythonpython-3.xpass-by-reference

解决方案


默认情况下,您应该具有__setattr__

class Foo:
    a = 0
    b = 0

f = Foo()
print(f.a)
# 0

f.a = 9
print(f.a)
# 9

f.__setattr__("a", 99)
print(f.a)
# 99

setattr(f, "a", 900)
print(f.a)
# 900

推荐阅读