动态查找和“替换”方法时发生冲突

2022-01-30 14:47:51 标签 python-3.xdynamicmetaprogramming

我有一个由静态方法a的“列表”组成的类。我想用一个类装饰器元来改变它的行为,它通过执行方法m来作用于这个例子内容中的一个特定的静态方法。

我最初的尝试CASE=2没有像预期的那样工作,所以我开始了我的案例研究。我引入了一个新类B,它对另一个方法信息的实现略有不同,但引发了一个有趣的错误,并引入了一个新类C,只是没有方法信息。

情况2:贪婪的情况

D [i] = classmethod(lambda CLS *args: MCS。M (getattr(target_cls i)(*args)))它不能正常工作,也许太多嵌套动态表达式?

情况1:它本质上是情况2但表达式被分成两行,它是可行的

   o = getattr(target_cls, i)
   d[i] = classmethod(lambda cls, *args: mcs.m(o(*args)))

这里的代码

class Meta:
    def __new__(mcs, target_cls):
        if CASE == 1:
            print('case 1')
            d = {}
            for i in dir(target_cls):
                 if i == 'content':
                    o = getattr(target_cls, i)
                    d[i] = classmethod(lambda cls, *args: mcs.m(o(*args)))
        if CASE == 2:
            print('case 2')
            d = {}
            for i in dir(target_cls):
                 if i == 'content':
                    d[i] = classmethod(lambda cls, *args: mcs.m( getattr(target_cls, i)(*args)) )
        return type('AAA', (target_cls,), d)
    @classmethod
    def m(mcs, p):
        return '--> ', p
class A:
    @staticmethod
    def content(response):
        return 'static_method', response
    @staticmethod
    def info(response):
        return response
class B:
    @staticmethod
    def content(response):
        return 'static_method', response
    @staticmethod
    def info(response):
        response.sort()
        return response
class C:
    @staticmethod
    def content(response):
        return 'static_method', response
# call the "content" class-method of each class for all different cases
for cls in (A, B, C):
    print(cls.__name__)
    for case in range(1,3):
        CASE = case
        R = Meta(cls)
        try:
            print(R.content('ppp'))
        except Exception as e: print(e)
    
    print()

输出

A
case 1
('--> ', ('static_method', 'ppp'))
case 2
('--> ', 'ppp')        # no decoration
B
case 1
('--> ', ('static_method', 'ppp'))
case 2
'str' object has no attribute 'sort'  # <- complained about the other method
C              # <- this is ok BUT I removed the other method!
case 1
('--> ', ('static_method', 'ppp'))
case 2
('--> ', ('static_method', 'ppp'))  # <- here the decoration took place

问题是,如果是语言的限制,为什么情况2行不通呢?

额外问题:如何解释B类案例2的错误

###我猜这个问题是由循环和起源的事实,每个语句都没有自己的范围(在循环中)。通过i as a key parameter of the lambda fixed the problem.

的一个关键参数lambda fixed the problem.

固定的问题。

class Meta:
    def __new__(mcs, target_cls):
        d = {}
        for i in dir(target_cls):
             if i == 'content':
                d[i] = classmethod(lambda cls, *args, m_name=i: mcs.m( getattr(target_cls, m_name)(*args)) )
    
        return type('AAA', (target_cls,), d)
    @classmethod
    def m(mcs, p):
        return '--> ', p
class A:
    @staticmethod
    def content(response):
        return 'static_method', response
    @staticmethod
    def info(response):
        return response
print(A.content)
print(Meta(A).content)
print(Meta(A).content('a'))
print(Meta(A).info)

输出

<function A.content at 0x7f04500740d0> # original static method
<bound method Meta.__new__.<locals>.<lambda> of <class '__main__.AAA'>> # class method
('--> ', ('static_method', 'a'))
<function A.info at 0x7f0450074040>
阅读全文

▼ 版权说明

相关文章也很精彩
推荐内容
更多标签
相关热门
全站排行
随便看看

错说 cuoshuo.com —— 程序员的报错记录

部分内容根据CC版权协议转载;网站内容仅供参考,生产环境使用务必查阅官方文档

辽ICP备19011660号-5

×

扫码关注公众号:职场神器
发送: 1
获取永久解锁本站全部文章的验证码