用于包含类标识的类的 Python 装饰器

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

基本上我有一个基类和一个元类以及大量使用两者的类 我想避免一遍又一遍地做

class Name(Base, metaclass=Meta)
,而是这样做

@deco
class Name:

我已经有一个这样的装饰器了:

def deco(cls):
    return Meta(cls.__name__, (Base, cls), dict(vars(cls)))

并且它有效,问题是它删除了原始类的身份,例如:

  • 当鼠标悬停在该类的变量上时,vscode 会说它是一个

    _class_Meta
    对象,而不是
    Name
    对象

  • print(Name().__doc__)
    按预期工作,但将鼠标悬停在所述对象上不会显示任何文档字符串

  • Name
    Base
    类的函数和变量甚至根本无法被vscode识别,只能识别元类的属性

我基本上在寻找类似 functools.wraps 装饰器的东西

python python-decorators metaclass
2个回答
0
投票

为什么会发生这种情况以及为什么你不应该首先这样做:
你无法从 vscode 获得任何文档字符串,因为这非常 hacky,因此 vscode 无法理解它,因为它非常不符合 Python 风格,所以它无法向你显示正确的工具提示。
永远记住:

Explicit is better than implicit.
- Python 之禅(自己阅读:
import this
)。这甚至不值得,它只会让你的代码变得更复杂,可读性/理解性更差,是的,即使对你自己来说也是如此。


0
投票

您可以创建一个新的基类,以

Base
作为基类,以
Meta
作为元类,这样其他类就可以从新基类继承:

class Meta(type):
    def __call__(cls):
        print('new instance')
        return super().__call__()

class Base:
    def __init__(self):
        print('base')

class NewBase(Base, metaclass=Meta):
    pass

class Name(NewBase):
    pass

print(Name())

输出:

new instance
base
<__main__.Name object at 0x1467a61a4b80>

演示:https://ideone.com/UOfMzv

© www.soinside.com 2019 - 2024. All rights reserved.