1

I have base class which is singleton, i need to inherit that in my another class but i get error message as TypeError: Error when calling the metaclass bases function() argument 1 must be code, not str

Can someone help with this. Below is sample code.

def singleton(cls):
  instances = {}
  def getinstance():
    if cls not in instances:
      instances[cls] = cls()
    return instances[cls]
  return getinstance

@singleton
class ClassOne(object):

  def methodOne(self):
    print "Method One"

  def methodTwo(self):
    print "Method Two"


class ClassTwo(ClassOne):
  pass
santosh
  • 3,061
  • 3
  • 17
  • 24
  • I think you made a design problem ... a singleton means where will be only one, if you have a derived class you would have multiple (2) instances of the base class. Are you sure you need a singleton? – Michel Keijzers Sep 27 '16 at 11:28
  • So `locals()` not work ? – dsgdfg Sep 27 '16 at 11:39
  • The need is ClassOne and ClassTwo both are singleton, classOne has functionality of ClassTwo and few additional support, so i need to use classOne methods instead of ClassTwo. changing these all over is major change hence wanted to implement using inheritance – santosh Sep 27 '16 at 11:40
  • i made changes like this @singleton class ClassOne(object): def methodOne(self): print "Method One" def methodTwo(self): print "Method Two" class ClassTwo(ClassOne): pass – santosh Sep 27 '16 at 11:42
  • @santosh [edit] the question, code is unreadable in comments. I'd also recommend you put a few `print`s in to better understand the control flow through your code. – jonrsharpe Sep 27 '16 at 11:43
  • According to your code, because of the decorator ClassOne is defined as the function `getinstance`. Functions cannot be inherited in Python, which is what you are trying to do with `ClassTwo`. – Frodon Sep 27 '16 at 11:57
  • Is [this answer](http://stackoverflow.com/a/11517201/2531279) fits your needs ? – Frodon Sep 27 '16 at 12:17
  • Possible duplicate of [Is there a simple, elegant way to define singletons in Python?](http://stackoverflow.com/questions/31875/is-there-a-simple-elegant-way-to-define-singletons-in-python) – Frodon Sep 27 '16 at 13:34

1 Answers1

2

You must make the singleton a class instead of a function for derivation to work. Here is an example that has been tested on both Python 2.7 and 3.5:

class singleton(object):
    instances = {}
    def __new__(cls, clz = None):
        if clz is None:
            # print ("Creating object for", cls)
            if not cls.__name__ in singleton.instances:
                singleton.instances[cls.__name__] = \
                    object.__new__(cls)
            return singleton.instances[cls.__name__]
        # print (cls.__name__, "creating", clz.__name__)
        singleton.instances[clz.__name__] = clz()
        singleton.first = clz
        return type(clz.__name__, (singleton,), dict(clz.__dict__))

If you use this with your example classes:

@singleton
class ClassOne(object):

  def methodOne(self):
    print "Method One"

  def methodTwo(self):
    print "Method Two"


class ClassTwo(ClassOne):
  pass

classes A and B will both be singletons

Beware, it is uncommon to inherit from a singleton class.

Serge Ballesta
  • 121,548
  • 10
  • 94
  • 199