Reputation: 11064
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[2J\x1b[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: %s\n 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
)
Upvotes: 55
Views: 129189
Reputation: 193
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
Upvotes: 1
Reputation: 187
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")
Upvotes: 17
Reputation: 1124100
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.
Upvotes: 42