0

I have two classes for making pyqt5 windows. Inside class one I have a button with a function it is connected to.

Class One:

from PyQt5 import QtGui, QtWidgets, QtCore
from PyQt5.QtWidgets import QApplication, QMainWindow


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

        self.btn = QtWidgets.QPushButton(self)
        self.btn.setText('Button')

        self.btn.clicked.connect(self.func)

    def func(self):
        # ...

In class two, I have the same button and need the function, but I don't want to copy and paste code.

Class Two:

class OtherWindow(QtWidgets.QDialog):
    def __init__(self):
        super(OtherWindow, self).__init__()

        self.btn = QtWidgets.QPushButton(self)
        self.btn.setText('Button')

        # want the function but don't want to copy/paste

Would it be considered "bad practice" to do this? If so, what can I do instead?

  • 1
    How many lines of code does the function contain? – Robert Harvey May 26 '21 at 16:33
  • 1
    @RobertHarvey the function is 9 lines long. – Have a nice day May 26 '21 at 16:34
  • 1
    What does the function do? – Robert Harvey May 26 '21 at 16:35
  • 1
    @RobertHarvey it modifies the text in a qtextedit. – Have a nice day May 26 '21 at 16:35
  • 1
    In what way does it modify the text? – Robert Harvey May 26 '21 at 16:36
  • 1
    @RobertHarvey it encrypts the text. – Have a nice day May 26 '21 at 16:37
  • 2
    It sounds like the method has sufficient utility in its own right to make it a "shareable" method. https://www.reddit.com/r/Python/comments/2qupte/whats_the_best_way_to_share_a_simple_helper/ – Robert Harvey May 26 '21 at 16:40
  • 1
    But 9 lines of code is not a lot. If it's tightly bound to the qtextedit, you may be better off just copy/pasting. – Robert Harvey May 26 '21 at 16:40
  • 2
    What hinders you technically to refactor the function (or at least the main part of it) into a separate utility class? – Doc Brown May 26 '21 at 16:43
  • 1
    @DocBrown what would that entail? – Have a nice day May 26 '21 at 16:46
  • If your organization has standards about this, obey them. However, my intuition is to use a function not copy/paste. If there are specific speed performance requirements, copy & paste may work. I personally would 'decorate' with comment-lines that set it well apart from everything else, but not everyone likes that style and some oppose it. – JosephDoggie May 26 '21 at 16:48
  • 1
    @JosephDoggie how would I make the function apply to both classes? – Have a nice day May 26 '21 at 16:49
  • I was assuming that making function apply to both classes was do-able easily. If not, just copy and paste. – JosephDoggie May 26 '21 at 17:12
  • 1
    @JosephDoggie I tried having a global function, but I'm not able to pass in the `self` argument when I connect to the button `button.clicked.connect(func)`. – Have a nice day May 26 '21 at 17:13
  • 1
    Did you read [the Reddit post I linked?](https://www.reddit.com/r/Python/comments/2qupte/whats_the_best_way_to_share_a_simple_helper/) – Robert Harvey May 26 '21 at 17:40
  • 1
    @RobertHarvey Yes, but I'm not sure if it will help yet. – Have a nice day May 26 '21 at 17:41
  • Sorry, I'm not a python developer, just trying to provide general guidance on the 'when to use functions' issue. If something doesn't easily code to a function in the language you are using, that probably means it shouldn't be one! – JosephDoggie May 26 '21 at 18:45
  • 2
    I learned from the comments this is about a function that encrypts text, which is 9 lines long. This is all the information we need, none of which gets illustrated by the code you provided. – Martin Maat May 26 '21 at 20:56
  • 1
    @Haveaniceday: for not copy-pasting the code, refactoring the common code into a place where you can use it from both original places would be the usual choice. But since it seems you are hesitant, I suspect there might be some technical difficulty, that's why I asked. But as long as you ask about a function you hide from us, we can only guess around. – Doc Brown May 26 '21 at 21:07
  • 1
    ... note this question already got two close votes "needs details or clarity", one vote more and it will get closed. It would be really nice you could edit the 9-length function into it (or at least a scetch), to make it more clear for what that function is good for, which member functions are used inside etc. – Doc Brown May 27 '21 at 06:40

1 Answers1

4

If you want an example of calling the same function in two different classes without having to define it twice you already have one in the code provided:

self.btn = QtWidgets.QPushButton(self)

Actually you have two:

self.btn.setText('Button')

So the real question is, should you do that or just copy and paste the 9 lines?

Well there is a principle to consider here. Don't Repeat Yourself (DRY). But be sure you understand it before you apply it. I've talked about it before.

Some think DRY is something a static analysis tool can check just by looking for identical code. This is wrong because what we care about is spreading around places where code will have to change together. The principle (or admonition) that checks against this goes: "Make decisions in one place".

When someone cracks this encryption, and we have to update it, how hard are you making it to find everywhere it needs to be fixed?

If, however, the code just happens to look the same but it represents two different ideas that are free to be changed independently then copy as you like. Makes it easier to change independently anyway. Just be sure you're making these separate ideas clear somehow. Or the next coder is gonna refactor them into one because they don't know any better.

candied_orange
  • 102,279
  • 24
  • 197
  • 315