'Can't find classmethod over class name

I am trying to invoke classmethod over classname .AttributeError problem occurs

When I use @singleton ,I can't run with classname.functionname .It's must be classname().functionname Why does this happen?

def singleton(cls):
    '''
    单例
    :param cls:
    :return:
    '''
    _instance = {}

    def _singleton(*args, **kargs):
        if cls not in _instance:
            _instance[cls] = cls(*args, **kargs)
            # print(type(_instance[cls])) <class '__main__.Coco'>
        return _instance[cls]

    return _singleton


@singleton
class Coco():

    # def __new__(cls, *args, **kwargs):
    #     if not hasattr(Coco, "_instance"):
    #         if not hasattr(Coco, "_instance"):
    #             Coco._instance = object.__new__(cls)
    #             print(type(Coco._instance))
    #     return Coco._instance

    def __init__(self):
        print('coco')

    @classmethod
    def get_info(cls):
        print('coco is 18 ages old')

# print(Coco().get_info())
print(Coco.get_info())

Exception

Traceback (most recent call last):
  File "/Users/coco/Automation/AutoTestRes/scripts/python/coco.py", line 36, in <module>
    print(Coco.get_info())
AttributeError: 'function' object has no attribute 'get_info'


Solution 1:[1]

When you use a decorator in Python, like this:

@decorator_name
class class_name:
    ...

..., this is equivalent to doing this:

class class_name:
    ...
class_name = decorator_name(class_name)

This means that the value of the variable class_name is no longer necessarily a class, but instead it is whatever the return value of decorator_name is.

In your case, the class decorator singleton returns the function _singleton, not the actual class. So when you say:

print(Coco.get_info())

..., this is the same as saying:

print(_singleton.get_info())

...within the function.

Therefore, you get an AttributeError, because the function, which now has the name Coco, does not have that attribute.

To access the attribute of the class, you need to run the function because this will return an instance of the class, which will have the attribute.

It is no longer possible to access the class itself from the global scope.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Lecdi