0

Suppose we have a class

class foo():
    def __init__(self):
        self.data = 10
    ...

    def method(self):
        ...
        self.free_indices.append(self.l[self.start_p])
        var1 = self.l[self.search(var2[num])].pointer
        ...

It is clearly seen that the method and attribute calls within the class is too long and hence readability of code decreases. To fix that one could create a pair of methods

    def get_some_att(self, var2, num):
        return self.l[self.search(var2[num])].pointer

    def append_index(self):
        self.free_indices.append(self.l[self.start_p])

Which at the first glance seems reasonable, but suppose you have a dozen of such different calls, so what will you do? Will you create a dozen get_some_att methods and therefore decrease the overall execution speed by a dramatic amount. Or will you happily forget about all calls to increase speed, but make compromise on readability. So what is the true pythonic™ way of handling thst kind of dilemmas?

Nick Boe
  • 1
  • 1
  • 1
    How is `self.get_some_att(self.data)` more readable than `self.some_att[self.data]`? – Barmar Sep 30 '17 at 16:37
  • You're right. This was a bad example, I'll change to more relevant one. – Nick Boe Sep 30 '17 at 16:39
  • Maybe what you're looking for are property getters and setters? https://stackoverflow.com/questions/2627002/whats-the-pythonic-way-to-use-getters-and-setters – Barmar Sep 30 '17 at 16:43
  • Unfortunately, it won't help much. As you may see there are several self.something in one statement and implementing @property would require creating a bunch `if` statement inside each other. – Nick Boe Sep 30 '17 at 16:49
  • You can use more temporary variables to reduce the number of nested expressions, but I suspect your question boils down to one of class design that can't be answer in general. – chepner Sep 30 '17 at 16:56
  • I think this is just normal software engineering -- define functions when they provide a common abstraction, to implement DRY principles. Don't do it just to shorten occasional complex sequences -- you can make them more readable by breaking up into multiple statements. – Barmar Sep 30 '17 at 16:56
  • If you want to get into this in more detail, softwareengineering.stackexchange.com would probably be more appropriate. – Barmar Sep 30 '17 at 16:58

2 Answers2

0

According to PEP8, the preferred way to break long lines without using \ is wrapping your statements in parentheses. For instance:

class foo():
def __init__(self):
    self.data = 10

def method(self):
    self.free_indices.append(self.l[self.start_p])
    var1 = (
        self.l[self.search(var2[num])]
            .var3  # you can chain method/attribute calls vertically
    )
JAponte
  • 1,508
  • 1
  • 13
  • 21
  • So you're suggesting that I shouldn't bother creating `get` methods or procedures at all? Even for frequent ones? – Nick Boe Sep 30 '17 at 16:54
  • I suggest to try to simplify your data structures and make attribute names as clear as possible, and preferably refer to the attributes explicitly. Defining a bunch of getters and setters is convenient sometimes, but you should only have a handful of these. If you need to access an object's attribute dynamically, you can use `getattr`. – JAponte Oct 05 '17 at 19:12
0

Whether having a single method to do multiple tasks or breaking them into a separate one, get_some_att and append_index, is all about how you design the class/module.

Its not just about readability but maintainability too. Also having a separate method for a specific task is not only help you to access them when you need them in future but also you can enhance the code in case of any exceptions occurred or required enhancement further. Therefore having a separate methods( for each individual job) will eventually help you to traceback the exceptions and give you freedom to modify the only section.

So I will say in long run of (large/very large) projects (which indeed will be with time), its absolute necessary to have a separate methods for each individual jobs for better readability, maintainability and easy to debug and fix.

Yes I agree the execution time probably cost you little more but worth doing it because it will save you a lot of development time, plus help you trace the error easily on production.

Now coming to the pythonic way of doing the code then I will suggest you to use a tool pylint or flake8 to check file complexity.

Nonetheless, having a separate methods for all individual tasks is worth doing when you know it might require for another places as well in near future(practising DRY)

MaNKuR
  • 2,578
  • 1
  • 19
  • 31