Question

Python style question.

Sometimes I assign classes to variables so I can instantiate them elsewhere, eg:

class GuitarItem():
    pass

class SuperClass():
    def get_instance(self):
        return self.Item()

class SubClass(SuperClass):
    Item = GuitarItem

class SubClass2(SuperClass):
    Item = PianoItem

Is this good style? Am I missing a more idiomatic way to do this? It worries me because item is not capitalised (as it is a variable) so it 'looks' like a method call.

UPDATE: As per comments from Hyperboreus I am capitalising the Item which looks more sensible to me as well. Otherwise this seems absolutely fine.

Was it helpful?

Solution 2

Not quite sure, but maybe you are looking for something along these lines. And yes, why not give a class another name in another scope.

#! /usr/bin/python3

class GuitarItem: pass

class PianoItem: pass

class SuperClass:
    def makeItem (self): #or whatever you want to do with the Item class
        return type (self).Item ()

class SubClass (SuperClass): Item = GuitarItem

class SubClass2 (SuperClass): Item = PianoItem

print (SubClass ().makeItem () )
print (SubClass2 ().makeItem () )

This will first create a Guitar and then a Piano.

OTHER TIPS

To address your main question :

Sometimes I assign classes to variables so I can instantiate them elsewhere (...) Is this good style? Am I missing a more idiomatic way to do this?

Python's classes (as well as functions, methods, modules etc) are plain object, just like anything else, so yes it is "good style" and no, there's no "more idiomatic way".

It worries me because item is not capitalised (as it is a variable) so it 'looks' like a method call.

It actually ends up being a method call (it's calling the __call__ method of the metaclass, which in turn calls the __new__ method of the class). Also FWIW you don't care whether item is actually a class, any callable returning the expected object would (and will) work as well, so it makes no sense CamelCasing it.

I would suggest using factory method pattern, because its very similar to what you've done and industry knows this pattern. http://en.wikipedia.org/wiki/Factory_method_pattern

class GuitarItem(): pass 
class PianoItem(): pass

class SuperClass():

    def __init__(self)
        self.item_instance = self.new_item()

    def new_item(self):
        """Explain why it should provide item."""
        raise NotImplementedError("Subclass of SuperClass must provide new_item method")


class SubClass(SuperClass):
    def new_item(self):
        return GuitarItem()

class SubClass2(SuperClass):
    def new_item(self):
        return PianoItem()
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top