Using private static methods

72

Solution 1

A private static method by itself does not violate OOP per se, but when you have a lot of these methods on a class that don't need (and cannot*) access instance fields, you are not programming in an OO way, because "object" implies state + operations on that state defined together. Why are you putting these methods on that class, if they don't need any state?

(*) = In principle, due to the class level visibility in Java, a static method on a class has access to instance fields of an object of that class, for example:

class Test
{
  int field = 123;

  private static void accessInstance(Test test)
  {
    System.out.println(test.field);
  }
}

You need to pass in the reference to an instance (this pointer) yourself of course, but then you are essentially mimicking instance methods. Just mentioning this for completeness.

Solution 2

As mentioned above, private static methods are often useful for organizing re-used logic and reducing/eliminating repeated code. I'm surprised that I haven't noticed any mention of performance in this discussion. From Renaud Waldura's 'The Final Word on Final':

(Note, private static methods are implicitly final)

"Since a final method is only implemented in the declaring class, there is no need to dynamically dispatch a call to a final method, and static invocation can be used instead. The compiler can emit a direct call to the method, bypassing entirely the usual virtual method invocation procedure. Because of this, final methods are also candidates for inlining by a Just-In-Time compiler or a similar optimization tool. (Remember, private/static methods are already final, therefore always considered for this optimization.)"

Check out the whole paper: http://renaud.waldura.com/doc/java/final-keyword.shtml

Solution 3

private or public doesn't make a difference - static methods are OK, but if you find you're using them all the time (and of course instance methods that don't access any instance fields are basically static methods for this purpose), then you probably need to rethink the design. It's not always possible, but most of the time methods should reside with the data they operate on - that's the basic idea of OOP.

Solution 4

I don't necessarily see any real problem with what you are doing, but my first question would be if the method doesn't require access to any instance fields, then what is it doing in that class in the first place?

Share:
72
abrzozowski
Author by

abrzozowski

Updated on March 27, 2020

Comments

  • abrzozowski
    abrzozowski over 4 years

    I want to create a script that takes two arguments that should be consumed:

    • directory_path,
    • files -- the list of files under the directory_path argument.

    I've written something like that:

    #!/usr/bin/python3
    
    import argparse
    import os
    
    import argcomplete
    
    if __name__ == '__main__':
        parser = argparse.ArgumentParser()
        parser.add_argument("directory_path",
                            help="a path to some directory",
                            nargs=1)
    
        # conditional choices of an argument
        conditional_choices = [os.listdir(parser.parse_known_args()[0].directory_path[0])]
        parser.add_argument("files",
                            metavar="FILES",
                            nargs='+',
                            choices=conditional_choices)
    
        argcomplete.autocomplete(parser)
        args = parser.parse_args()
    
        print("directory_path {}".format(args.directory_path))
        print("files {}".format(args.files))
    

    So the files argument depends on the directory_path argument.

    Using: Python3.8

    Problems

    For the above snippet, the bash-completion (built from register-python-argcomplete3) for a files argument doesn't work. If I push enter after the valid command (with path and file) then I'm getting an error

    error: argument FILES: invalid choice: ...
    
    • hpaulj
      hpaulj almost 3 years
      Does this work without the completer? While I understand argparse well, I haven't done anything with the completer.
    • hpaulj
      hpaulj almost 3 years
      Does the error message include the problem string and the valid choices? If so, are they what you expect?
    • hpaulj
      hpaulj almost 3 years
      Too many [] in [os.listdir(...]. The error message should list invalid choice: 'xxx' (choose from '.hdfview2.11', ... without []
    • abrzozowski
      abrzozowski almost 3 years
      No, it doesn't work without the completer too. I've recorded how its works on my computer asciinema.org/a/QD9t1fA584QwzBkaowZDwM64F [In case of asciinema link expired] If I call sample . stackoverflowfile (with the valid file) then I'm getting usage: sample [-h] directory_path FILES [FILES ...] sample: error: argument FILES: invalid choice: 'stackoverflowfile' (choose from ['sample', '.idea', 'stackoverflowfile'])
    • hpaulj
      hpaulj almost 3 years
      You have generated a bad choices. Compare that with a simple choices=['one','two'] list.
    • abrzozowski
      abrzozowski almost 3 years
      Ok, but I would like to have choices of files argument that will be dynamically changed based on the value of the directory_path argument. So I can't predefine values of choices. If I change choices of files to static choices=['one','two'] it works (sample . one gives valid output)