【发布时间】:2020-08-05 20:42:39
【问题描述】:
我在一个类中有一些对类成员进行操作的函数。除了它们操作的类成员之外,这些函数几乎相同。为了避免一遍又一遍地键入函数,只更改被更改的类成员,我创建了一个函数,其中一个参数是要更改的类成员。
这是一个非常简化的版本:
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次左右,只更改正在修改的类成员、转换状态、时间和结束状态,但我宁愿减少代码重复。
我也尝试过使用装饰器来解决这个问题:
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
但这也行不通。
如何推广这个函数以减少代码重复?
谢谢。
【问题讨论】:
-
类似
setattr? -
你确定你真的想要类属性吗?我怀疑
a和b应该是 instance 属性,您可以直接设置它们而无需任何设置器样板。 (如果你确实发现你以后需要setter,你可以定义属性。) -
您还可以使用列表的类成员获得类似指针的效果。这就像拥有一个使用其索引取消引用的指针。我发布了一个答案来证明这一点。
-
我好心但非常强烈地建议您 1/ 阅读 full Python official tutorial,2/ 阅读 doc on Python's data model,最后 3/ 阅读此 very good article about python's names and bindings。 Python 与 C++ 完全不同,所以你不能期望只用 Python 编写 C++ 代码;-)
标签: python python-3.x pass-by-reference