Python Classes without using def __init__(self)

Question:

I am writing a series of text menus. With the class and sub class below it runs with no issues. But I am reviewing my coding and I am wondering….is it ok that I didn’t use def __init__(self) in the classes? Should I have placed the data members in def __init__(Self): such as self.images = (), self.options =()? If I did that then I could not use the abc module for restrains, correct?

class BaseMenu(object):
    __metaclass__ = abc.ABCMeta

    @abc.abstractproperty
    def options(self):
        pass

    @abc.abstractproperty
    def menu_name(self):
        pass

    def display(self):
        header = "FooBar YO"
        term = getTerminalSize()
        #sys.stdout.write("x1b[2Jx1b[H")
        print header.center(term, '*')
        print self.menu_name.center(term, '+')
        print "Please choose which option:"
        for i in self.options:
            print(
                str(self.options.index(i)+1) + ") "
                + i.__name__
            )
        value = int(raw_input("Please Choose: ")) - 1

        self.options[value](self)

class Servers(BaseMenu):

    menu_name = "Servers"
    images = ()
    foo = ()

    def get_images(self):
        if not self.images:
            self.images = list_images.get_images()
        for img in self.images:
            print (
                str(self.images.index(img)+1) + ") "
                + "Name: %sn    ID: %s" %
                (img.name, img.id)
                )

    def get_foo(self):
        if not self.foo:
            self.foo = list_list.get_list()
        for list in self.foo:
            print "Name:", list.name
            print "  ID:", list.id
            print

    def create_servers(self):
         create_server.create(self)

    options = (
        get_images,
        get_foo,
        create_servers
        )
Asked By: dman

||

Answers:

Your code is perfectly fine. You don’t have to have an __init__ method.

You can still use __init__, even with an ABC. All that the ABC meta tests for is if the names have been defined. Setting images in an __init__ does requires that you define a class attribute, but you can set that to None at first:

class Servers(BaseMenu):

    menu_name = "Servers"
    images = None
    foo = None

    def __init__(self):
        self.images = list_images.get_images()
        self.foo = list_list.get_list()

Now you can set constraints on the ABC requiring that a images abstract property be available; the images = None class attribute will satisfy that constraint.

Answered By: Martijn Pieters

Your code is fine. The example below shows a minimal example.
You can still instantiate a class that doesn’t specify the __init__ method. Leaving it out does not make your class abstract.

class A:
    def a(self, a):
        print(a)
ob = A()
ob.a("Hello World")
Answered By: Chandan

Just to add to the other answers, omitting __init__() could be useful when we want to call only certain methods of a class because instantiating an object repeatedly could become expensive computationally in some use cases.

For example, suppose you have a calculator application and Python acts as an API and will provide the results from the calculator to the client. Consider the following function in main.py:

import operations

def main():
  ### Some code here ###
  
  result = operations.Operations.calculate_value(value_1)
  # "Operations" is the name of the class in the module.
  # "value_1" is the data being sent from the client.
  
  ### Some code here ###

  return result

For simplicity, I have not included the boilerplate for handling API calls. main() will be called every time a new request needs to be processed by the server. So, creating an instance of the class every time when a request arrives will be expensive if the number of users accessing it is high.

Considering the above example, we can define "Operations" in operations.py as shown below:

class Operations:
  # Omit __init__() since we will be using only class and static methods.

  # You can use @staticmethod decorator as well here
  # if you don't have any class variables or if you
  # do not need to modify them.
  @classmethod
  def calculate_value(value):
    ### Some code here ###
    
    calculated_value = value + 1
    
    ### Some code here ###

    return calculated_value
Answered By: chess_madridista
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.