Python 理念:使用类似于包装函数/类的“模块包装器”装饰模块导入,以创建模块模板

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

问题:这个想法值得吗?还是我误解了什么?

@装饰者 导入模块

@装饰者 从 abc 导入 d

在我的理解中,模块(或 python.py 文件)就像 C# 中的静态类,您可以在其中定义函数变量、类等,但不能从中创建实例。

当我想使用静态类时,我会这样做

class StaticClass:
     propA = "value"
     propB = "value"
     ...
     @staticmethod
     def funA(cls): pass
     
     @staticmethod
     def funB(cls): pass

但我发现编写所有这些“@staticmethod”并且必须引用 cls 作为参数并不方便

所以我将其移到课堂之外的模块中

     
propA = "value"
propB = "value"

def funA():
    pass
def funB(): 
    global propA, probB
    pass

唯一的吸引力似乎是在编辑模块的变量时我需要使用 global 关键字。

在 c# 中,你可以创建模板类,所有这些想法都是为了能够创建 kindof 模块模板/在我的理解中,模板化静态类无需样板 @staticmethod def a(cls): ... stuff

假设我有一个具有许多功能的模块,我想用相同的装饰器来装饰它。 这些装饰器接受一个参数 v。我们可以通过定义一个新的 Type

将变量 v 标记为模板变量
class Template(Any): pass

# module.py
v:Template = "somevalue"
@x(v)
def a():...

@x(v)
def b():...

...

现在我想多次导入模块,但我希望参数 v 每次都是另一个。

我们可以定义一个包装函数,将模块作为参数并修改模块并返回它。

def module_decorator(globals,vars,...): #the parameters are what ever properties a module can have

or we create a new Type for Modules where those parameters are stored

def module_decorator(module:Module,otherparams,*,v):
    copied_module = module.copy()
    #modify module ...

    copied_module.vars["v"].set(v) # set the v parameter of module.py
    copied_module.vars.filterByType(Template)["v"].set(v) # set the v parameter of module.py

    # we could also decorate all functions with some wrapper function  at this point
so i dont have to decorate all the functions seperately with @x(v)

    # copied_module.functions
    # copied_module.classes
    # copied_module.imported_modules
    
    return copied_module

所以现在我们可以轻松做到


@module_decorator(v="A")
import module as versionA


@module_decorator(v="B")
import module as versionB

...

在我的用例中,我可以使用它来创建一个模块,该模块实现相同的 sql 查询但在不同的 sql 表上,并且我将表名称传递给模板模块。

唯一的吸引力是,当查看模块本身时,你无法知道它是否用作模板。

这可能会导致混乱,但我相信无论如何它都是有益的。

自我批评: 我可能不是第一个有这个想法的人,而且我可能误解了模块的概念。 Maby 将模块用作 C# 静态类并想要对它们进行模板化是一种不好的做法,这不是 Pythonic 的事情。

无论如何,由于到目前为止我还没有找到有关此主题的任何内容,因此我想开始对此进行讨论并从中学习。

python templates module decorator wrapper
1个回答
-1
投票

避免重复将相同的装饰器应用于类的所有方法的一种方法是创建一个为您执行此操作的类装饰器:

def all_decorated_with(decorator):
    def _decorator(cls):
        for name, obj in vars(cls).items():
            if callable(obj) and not (name.startswith('__') and name.endswith('__')):
                setattr(cls, name, decorator(obj))
        return cls
    return _decorator

这样:

@all_decorated_with(classmethod)
class Foo:
    a = None

    def set(cls, value):
        cls.a = value

    def get(cls):
        return cls.a

Foo.set(1)
print(Foo.get())

输出:

1

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

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