将类的名称传递给函数,在方法之外分配给类属性

问题描述 投票:2回答:2

Python 3.7:

我有一个类定义,其中class属性根据类名分配一个值,该值用于类中的装饰器。

我正在寻找“正在定义的班级”的代名词。

这是一个例子:

class MyClass:

    # NameError: name '__class__' is not defined
    class_logger = find_logger(__class__.__name__)

    # __init__ is not important
    def __init__(self):
        # This works!
        self.logger = find_logger(__class__.__name__)

    @mydecorator(class_logger)
    # mymethod is not important
    def mymethod(self):
        return 1

什么是“正在定义的班级”的合适代名词?

(这类似于How to get the current Python class name in __init__ regardless of the class of "self"?,但在那里,问题是“在init的定义中”,当时是2.7。Python 3.x解决了这个问题。)

python class python-3.7
2个回答
4
投票

当类定义尚未完成评估时,无法保证类对象存在且可供用户访问。即使它是可访问的,也可能没有初始化到你可以对它做任何有用的事情。

也就是说,您可以获得该课程的名称。 __qualname__是一个属性,它包含类/函数/方法/描述符/生成器实例的qualified name。您应该能够从类的定义中访问它。

class Fred:
    print("Fred's qualname:", __qualname__)
    class Barney:
        print("Barney's qualname:", __qualname__)

结果:

Fred's qualname: Fred
Barney's qualname: Fred.Barney

如果未在文件级定义类,则可能需要执行一些字符串操作以将其名称与路径的其余部分分开。例如,将上面的示例更改为print("Barney's qualname:", __qualname__.rpartition(".")[-1])以获得“Barney”而不是“Fred.Barney”。


尽管我付出了最大的努力,但我找不到明确证实__qualname__作为常规名称而不是作为属性访问时具有合理价值的文档。我并不完全相信这是明确定义的行为,因此我认为我无法毫无保留地认可它以获得生产质量的代码。


2
投票

要在定义期间使用类名,您还可以使用带有__prepare__方法的元类:

def find_logger(name):
    return name + '_logger'


class PrepareClassLogger(type):
    def __prepare__(name, bases, **kwargs):
        return {'class_logger': find_logger(name)}


class MyClass(metaclass=PrepareClassLogger):
    pass

print(MyClass.class_logger)  # MyClass_logger
© www.soinside.com 2019 - 2024. All rights reserved.