更改变量在不同类中的值,而无需重写方法

时间:2019-01-14 10:50:24

标签: python inheritance methods multiple-inheritance class-method

我有两节课。在一个类中,我有很多基于变量运行的方法。

在第二个类中,我想定义第二个变量,当该变量为true时,一类的方法将在其中运行。

但是,我不确定该怎么写。

我想知道如何定义新变量(在第二类中),并确保第二类中的该变量替换第一类中的变量(当此变量为true时)。

例如:

class One():
   def MethodOne( self ):

        if self.this.VariableOne:
          do something
          do something else
          do another thing
          return something

class Two(One):
   def MethodOne( self ):

        if self.this.VariableTwo:
          run all the other code in MethodOne(), (if the variable is VariableTwo, but replacing VariableOne.

我不确定这里的最佳方法。

但是我仍然希望运行MethodOne方法(从不同的类),但是要使用不同的变量。

2 个答案:

答案 0 :(得分:0)

如果我正确理解了您的问题,那么我认为最简单的方法是在One上创建一个类变量,只需将其设置为false。像这样:

import sys
import time
import PyQt5

from PyQt5 import QtCore, QtWidgets
from PyQt5.QtCore import QRunnable, pyqtSignal, QObject
from PyQt5.QtWidgets import QApplication, QMainWindow, QWidget, QDialog


class CaptureDataTaskStatus(QObject):
    progress = pyqtSignal(int, int)  # This signal is used to report progress to the UI thread.
    captureDataFinished = pyqtSignal(dict)  # Assuming your result is a dict, this can be a class, a number, etc..


class CaptureDataTask(QRunnable):
    def __init__(self, num_measurements):
        super().__init__()

        self.num_measurements = num_measurements
        self.status = CaptureDataTaskStatus()

    def run(self):
        for i in range(0, self.num_measurements):
            # Report progress
            self.status.progress.emit(i + 1, self.num_measurements)
            # Make your equipment measurement here
            time.sleep(0.1) # Wait for some time to mimic a long action

        # At the end you will have a result, for example
        result = {'a': 1, 'b': 2, 'c': 3}

        # Send it to the UI thread
        self.status.captureDataFinished.emit(result)


class ResultWindow(QWidget):
    def __init__(self, result):
        super().__init__()

        # Display your result using widgets...
        self.result = result

        # For this example I will just print the dict values to the console
        print('a: {}'.format(result['a']))
        print('b: {}'.format(result['b']))
        print('c: {}'.format(result['c']))


class MainWindow(QMainWindow):
    def __init__(self, *args, **kwargs):
        super(MainWindow, self).__init__(*args, **kwargs)

        self.result_windows = []

        self.thread_pool = QtCore.QThreadPool().globalInstance()

        # Change the following to suit your needs (I just put 1 here so you can see each task opening a window while the others are still running)
        self.thread_pool.setMaxThreadCount(1)

        # You could also start by clicking a button, menu, etc..
        self.start_capturing_data()

    def start_capturing_data(self):
        # Here you start data capture tasks as needed (I just start 3 as an example)
        for setting in range(0, 3):
            capture_data_task = CaptureDataTask(300)
            capture_data_task.status.progress.connect(self.capture_data_progress)
            capture_data_task.status.captureDataFinished.connect(self.capture_data_finished)
            self.thread_pool.globalInstance().start(capture_data_task)


    def capture_data_progress(self, current, total):
        # Update progress bar, label etc... for this example I will just print them to the console
        print('Current: {}'.format(current))
        print('Total: {}'.format(total))

    def capture_data_finished(self, result):
        result_window = ResultWindow(result)
        self.result_windows.append(result_window)
        result_window.show()


class App(QApplication):
    """Main application wrapper, loads and shows the main window"""

    def __init__(self, sys_argv):
        super().__init__(sys_argv)

        self.main_window = MainWindow()
        self.main_window.show()


if __name__ == '__main__':
    app = App(sys.argv)   
    sys.exit(app.exec_())

答案 1 :(得分:0)

我认为最好的方法是对所有在元类中实现的功能使用装饰器(来自Attaching a decorator to all functions within a class):

class TheMeta(type):
    def __new__(cls, name, bases, namespace, **kwds):
        # my_decorator = cls.my_decorator (if the decorator is a classmethod)
        namespace = {k: v if k.startswith('__') else Variablecheck(v) for k, v in namespace.items()}
        return type.__new__(cls, name, bases, namespace)

装饰器:

def Variablecheck(func):
    @functools.wraps(func)
    def wrapper_Variablecheck(*args, **kwargs):
        # if inspect.isclass(type(args[0])):
        if args[0].this.VariableTwo:
            return func(*args, **kwargs)

然后,尝试一下:

class One(metaclass=TheMeta):
    # rest of the definition

否则,如果您想保持原始类不变,也可以将元类应用于继承类。