代码之家  ›  专栏  ›  技术社区  ›  Jimmyt1988

替代Python中的传递引用以帮助DRY

  •  0
  • Jimmyt1988  · 技术社区  · 3 年前

    我在用Python 3.9 。采取以下措施:

    class Something(QWidget):
        pass
    
    class SomethingElse(QWidget):
        pass
    
    class BaseWindow:
        def do_common_task(self, ptr_to_object: QWidget, new_widget: QWidget) -> None:
            # Do common stuff to new_widget.
            # Assign ptr_to_object here rather than in each method A.switch_obj_value and A.switch_another_obj_value
            ptr_to_object = new_widget
    
    class WindowA(BaseWindow):
        ptr_to_obj: QWidget
        something_widget: Something
        something_else_widget: SomethingElse
    
        def __init__(self) -> None:
            self.ptr_to_obj = None
            self.something_widget = None
            self.something_else_widget = None
    
        def switch_obj_value(self) -> None:
            self.something_widget: QWidget = Something()
            self.do_common_task(self.ptr_to_obj, self.something_widget)
            # self.ptr_to_obj will be None regardless of being set in Base.do_common_task.
    
        def switch_another_obj_value(self) -> None:
            self.something_else_widget: QWidget = SomethingElse()
            self.do_common_task(self.ptr_to_obj, self.something_else_widget)
            # self.ptr_to_obj will be None regardless of being set in Base.do_common_task.
    

    我已经去掉了应用程序的上下文。

    Python的问题是我无法通过 self.ptr_to_object 作为对的参考 do_common_task 因此对其执行的任何操作都发生在其自身的实例上。

    围绕这种无法通过引用传递的问题,Python技术是什么?

    编辑
    我提到“参考”可能把事情弄糊涂了。我的意思其实是“指针”,我真的为此道歉。当指针被传递到修改指针值的基类方法中时,我的指针不会在子类中更新。这就是为什么我认为,如果我有一个指针的引用,我可以改为更改值。

    感谢Samwise回答: 我添加了一个新类,并将其实例传递到函数中。这使得指针能够正确更新。

    也谢谢大家,非常有帮助。 enter image description here

    enter image description here

    2 回复  |  直到 3 年前
        1
  •  1
  •   chepner    3 年前

    我可能不知道你在问什么问题,但是 Base.do_common_task 将对的实例进行操作 A 如果那是调用它的实例。 似乎也没有理由通过任何与 ptr_to_object 作为该方法的论据;上的属性 self 是目标,而不是作为参数传递的其他变量。

    像这样的东西似乎就是你想要的,

    class Base:
        def do_common_task(self, new_widget: QWidget) -> None:
            # Do common stuff to new_widget.
            self.ptr_to_object = new_widget
    
    class A(Base):
        ptr_to_obj: QWidget
        something_widget: Something
        something_else_widget: SomethingElse
    
        def switch_obj_value(self) -> None:
            something_widget: QWidget = Something()
            self.do_common_task(something_widget)
            
        def switch_another_obj_value(self) -> None:
            something_else_widget: QWidget = SomethingElse()
            self.do_common_task(something_else_widget)
    

    但是,更清楚地描述你想要实现的目标,而不是描述你将如何用一种完全不同的数据模型在语言中做类似的事情,会有所帮助。

        2
  •  1
  •   Karl Knechtel    3 年前

    从概念上讲, Base 没有理由知道 A 类偶数 存在 ,没关系 A. 实例具有 ptr_to_object 属性。相应地,没有理由 do_common_task 应该赋予设定该值的责任。继承在这里无关紧要(事实上,在这个精简的例子中没有任何内容 证明 首先使用继承);任务由负责 A.

    class Base:
        def do_common_task(self, new_widget: QWidget) -> None:
            # Do common stuff to the new_widget.
            # We give the value back, so that the caller can use it.
            return new_widget
            # Notice that, in this setup, we could have equally well
            # created a new QWidget based off the input, instead of
            # modifying that widget.
    
    class A(Base):
        ptr_to_obj: QWidget
        something_widget: Something
        something_else_widget: SomethingElse
    
        def __init__(self) -> None:
            self.ptr_to_obj = None
            self.something_widget = None
            self.something_else_widget = None
    
        def switch_obj_value(self) -> None:
            self.something_widget: QWidget = Something()
            self.ptr_to_obj = self.do_common_task(self.something_widget)
    
        def switch_another_obj_value(self) -> None:
            self.something_else_widget: QWidget = SomethingElse()
            self.ptr_to_obj = self.do_common_task(self.something_else_widget)
    

    …当然,除非, 基础 实例在概念上也应该具有 ptr_to_object ,在这种情况下,您需要像@chepner的方法(其中假设 self.ptr_to_object 是被替换的东西,是硬编码的)。

    请记住 从函数中发送信息的正常方式是指定 return 值,而从函数调用中获取信息的正常方法是使用 回来 ed结果 .如果你有充分的理由通过修改论点来传达信息( 通过 参数)。但这些论点 属于呼叫者 。让调用上下文处理自己的数据结构。请