简体   繁体   中英

Get wrong output in python Singleton design pattern

I was making a Singleton design pattern and everything goes fine.

Look at the code below:

class Singleton():
    def __new__(cls):
        if not hasattr(cls, 'instance'):
            cls.instance = super().__new__(cls)
        return cls.instance

s1 = Singleton()
s2 = Singleton()

print(s1 is s2)
# True

But this is not Singleton because user can use delattr(Singleton,'instance') between creating s1 and s2 and with this simple function s1 is s2 returns False

So I decided to change instance to __instance (to stop user using delattr(Singleton,'instance') ) but when I do that I get False when printing s1 is s2 (My new code (__instance))

class Singleton():
    def __new__(cls):
        if not hasattr(cls, '__instance'):
            cls.__instance = super().__new__(cls)
        return cls.__instance

s1 = Singleton()
s2 = Singleton()

print(s1 is s2)
# False

But where is the problem? Why when I change instance to __instance the result I get is False?

(I know other methods of creating Singleton I Just want to know what is different in instance and __instance when I'm in the class and __instance is not private for myself)

Python name mangles the variable. Its called "_Singleton__instance" in the class __dict__ . You could use that name instead or use an exception handler for the assignment. In that case, python does the mangling for you and it would work for subclasses of Singleton also.

class Singleton():
    def __new__(cls):
        # could do this ....
        #if not hasattr(cls, '_Singleton__instance'):
        #    cls.__instance = super().__new__(cls)
        #return cls.__instance
        try:
            return cls.__instance
        except AttributeError:
            cls.__instance = super().__new__(cls)
            return cls.__instance

s1 = Singleton()
s2 = Singleton()

print(s1 is s2)

Of course its still easily defeated

delattr(Singleton, "_Singleton__instance")
s3 = Singleton()
print(s1 is s3)

Python is a very dynamic language and if someone wants to hurt themself, then have at it!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM