简体   繁体   English

Python对象组合 - 从调用它的类访问方法

[英]Python object composition - accessing a method from the class that called it

You'll have to forgive me, I am trying to teach myself OO but I have come across this problem with composition and 'has-a' relationships. 你必须原谅我,我正在努力教自己OO,但我遇到了这个问题,包括作文和“有一个”的关系。

class Main(object):
    def A(self):
        print 'Hello'
    def B(self):
        self.feature = DoSomething()

class DoSomething(object):
    def ModifyMain(self):
        #Not sure what goes here... something like
        Main.A()

def run():
    M = Main()
    M.B()

A real world example of the above simplification is a PySide application where Main is a MainWindow, and DoSomething is a dynamically created widget that is placed somewhere in the window. 上述简化的一个真实示例是PySide应用程序,其中Main是MainWindow,DoSomething是动态创建的小部件,放置在窗口的某个位置。 I would like DoSomething to be able to modify the status bar of the mainwindow, which is essentially calling (in Main) self.statusbar(). 我希望DoSomething能够修改主窗口的状态栏,主要是调用(在Main中)self.statusbar()。

If there is a shortcut in PySide to do this, Tops!! 如果PySide中有一个快捷方式可以做到这一点,Tops !! please let me know! 请告诉我! However, I'm actually after the more general Pythonic way to do this. 但是,我实际上是采用更普遍的Pythonic方法来做到这一点。

I think I'm close ... I just can't make it work... 我想我很接近......我无法让它发挥作用......

Why don't you use a signal and slot instead? 为什么不使用信号和插槽呢? That's a more Qt and OOP way of doing this. 这是更多的Qt和OOP方式。

In your dynamically created widget class: 在动态创建的窗口小部件类中:

self.modifyMain = QtCore.Signal(str)

In your main class: 在你的主要课程中:

@QtCore.Slot(str)
def changeStatusbar(self, newmessage):
    statusBar().showMessage(newmessage)

in you main class after creating your widget: 在创建窗口小部件后在主类中:

doSomething.modifyMain.connect(self.changeStatusbar)

And in you widget class, where you want to change the statusbar of main, you say: 在您要更改main的状态栏的widget类中,您说:

modifyMain.emit("Hello")

None of this is tested as I don't have a PySide installation handy. 这些都没有经过测试,因为我没有方便的PySide安装。

There are two problems with your code: 您的代码有两个问题:

  1. At no time do you call ModifyMain ; 你什么时候打电话给ModifyMain ; and
  2. Main.A() will result in an error, because A is an instance method, but you are calling it on a class . Main.A()将导致错误,因为A是实例方法,但您在上调用它。

You want something like: 你想要的东西:

class Main(object):
    def A(self):
        print 'Hello'
    def B(self):
        self.feature = DoSomething() # self.feature is an instance of DoSomething
        self.feature.ModifyMain(self) # pass self to a method

class DoSomething(object):
    def ModifyMain(self, main): # note that self is *this* object; main is the object passed in, which was self in the caller
        #Note case - main, not Main
        main.A()

def run():
    M = Main()
    M.B()

if __name__=="__main__": # this will be true if this script is run from the shell OR pasted into the interpreter
    run()

Your names all flout the usual python conventions found in PEP8 , which is a pretty good guide to python style. 你的名字都蔑视PEP8中常见的python约定,这是python风格的一个很好的指南。 I have left them as they were in your code, but don't copy the style in this example - follow PEP8. 我已将它们保留在您的代码中,但不要复制此示例中的样式 - 请遵循PEP8。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM