返回类混合物,在检查类的一个字段之后。

huangapple go评论61阅读模式
英文:

Return class mixin after checking a field of the class

问题

我想将一个混合类(MixinClass)添加到我已经拥有的类(A)中,但首先我需要检查该类是否有一个字段(atr)。这是因为类A可以来自两个不同的模块,其中一个模块中有一个字段attr,而另一个模块中没有。

我尝试过类似以下的方法,但不知道如何在方法中获取类A:

def check():
    class mixinClass(object):
        new_atr = None
    
    if hasatr(A, 'atr'):  # 我如何检查类是否具有这样的字段?
        return mixinClass

class A(check()):
   ...

请注意,上述代码中的“hasatr”函数需要您自行实现,用于检查类A是否具有名为“atr”的字段。

英文:

I want to add a mixin class (MixinClass) to a class (A) that I already have but first I need to check if that class has a field (atr) or not. This is because class A can come from two different modules, in one there is a field attr and in the other there is not.

I've tried something like this, but I don't know how I can get the class A into the method

def check():
    class mixinClass(object):
        new_atr = None
    
    if hasatr(A, 'atr'):  # How can I check that the class has such a field?
        return mixinClass

class A(check()):
   ...

答案1

得分: 0

你可以使用元类动态设置一个类的基类,在其中可以将条件基类的逻辑放在__new__方法中:

def mixin_if_hasattr(mixin, attr):
    class MixinIfHasattr(type):
        def __new__(metacls, name, bases, classdict):
            return super().__new__(
                metacls,
                name,
                bases + ((mixin,) if attr in classdict else ()),
                classdict
            )
    return MixinIfHasattr

这样:

class mixinClass:
    new_attr = None

class A(metaclass=mixin_if_hasattr(mixinClass, 'foo')):
    pass

class B(metaclass=mixin_if_hasattr(mixinClass, 'foo')):
    foo = None

print(A.__bases__)
print(B.__bases__)

输出:

(<class 'object'>,)
(<class '__main__.mixinClass'>,)

演示:https://replit.com/@blhsing/JointShabbyBetaversion

英文:

You can dynamically set the base class of a class with a metaclass, where you can put your desired logics of a conditional base class in the __new__ method:

def mixin_if_hasattr(mixin, attr):
    class MixinIfHasattr(type):
        def __new__(metacls, name, bases, classdict):
            return super().__new__(
                metacls,
                name,
                bases + ((mixin,) if attr in classdict else ()),
                classdict
            )
    return MixinIfHasattr

so that:

class mixinClass:
    new_atr = None

class A(metaclass=mixin_if_hasattr(mixinClass, &#39;foo&#39;)):
    pass

class B(metaclass=mixin_if_hasattr(mixinClass, &#39;foo&#39;)):
    foo = None

print(A.__bases__)
print(B.__bases__)

outputs:

(&lt;class &#39;object&#39;&gt;,)
(&lt;class &#39;__main__.mixinClass&#39;&gt;,)

Demo: https://replit.com/@blhsing/JointShabbyBetaversion

huangapple
  • 本文由 发表于 2023年3月1日 15:32:06
  • 转载请务必保留本文链接:https://go.coder-hub.com/75600682.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定