ChrisW
ChrisW

Reputation: 5048

Propagating variables through classes

If I have the following code

class A:
  def __init__(self):
    a = 1
    self.b = B(a)

class B:
  def __init__(self,i):
    self.c = C(i)

class C:
  def __init__(self,j):
    print j

if __name__ == '__main__':
  A()

then running the programme will print 1. Apart from making global variables (which I know are bad!) is there a way of calling a from C without having to propagate the variable through calls? Or would that be equally bad? (I'm sure this shows glaring gaps in my OO understanding, but it's always been a question in the back of my mind...)

Real world example

Hmm, I don't consider myself to be a programmer (although it's what I've ended up doing), so I know there are massive gaps in my understanding. I hope that this example shows what I'm trying to ask. In this instance, I wanted to know if there was a way of calling the server port number directly in Browser without having to send the variable via webwidget. Perhaps the example is a bit contrived and the code could be rewritten in a better way...

import BaseHTTPServer, CGIHTTPServer, os, sys
from PyQt4 import QtCore
from PyQt4.QtCore import *
from PyQt4.QtGui import *  
from PyQt4.QtWebKit import QWebView
from PyQt4.QtNetwork import *

class server:

  def initServer(self):
    server = BaseHTTPServer.HTTPServer
    httpd = server(("",0), CGIHTTPServer.CGIHTTPRequestHandler)
    return httpd

class wrapper(QMainWindow):

  def __init__(self):
    super(wrapper, self).__init__()
    self.createActions()
    self.createToolbar()
    self.cs = server().initServer()

  def createToolbar(self):
    self.toolbar = self.addToolBar("MainMenu")
    self.toolbar.addAction(self.web)

  def createActions(self):
    self.web = QAction("web", self, triggered=self.webwidget)

  def webwidget(self):
    self.webw = webwidget(self.cs.server_port)
    self.setCentralWidget(self.webw)

class webwidget(QWidget):

  def __init__(self,port):
    super(webwidget, self).__init__()

    self.b = Browser(port)
    self.grid = QGridLayout()
    self.grid.addWidget(self.b,0,1)
    self.setLayout(self.grid)

class Browser(QWebView):

  def __init__(self,port):
    QWebView.__init__(self)
    self.load(QUrl('http://localhost:'+str(port)+'/test.htm'))
    self.loadFinished.connect(self._result_available)

  def _result_available(self, ok):
    frame = self.page().mainFrame()

if __name__ == '__main__':
  app = QApplication(sys.argv)
  gui = wrapper()
  gui.show()
  app.exec_()

Upvotes: 0

Views: 279

Answers (1)

eandersson
eandersson

Reputation: 26362

You are probably looking for something like Polymorphism here.

class A(object):
  def __init__(self):
    self.a = 1

class B(A):
  def __init__(self):
    super(B, self).__init__()

class C(B):
  def __init__(self):
    super(C, self).__init__()
    print self.a

if __name__ == '__main__':
  C()

In this case C is based on B, that is then based on A. This allows C to inherit the values of A and B, and B inherit the values of A.

This would obviously flip the solution around as you need to call C instead of A first.

Another change here would be the use of the self keyword to assign the variable a to the class itself.

Upvotes: 2

Related Questions