首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Python魔术元类创建

Python魔术元类创建
EN

Stack Overflow用户
提问于 2018-05-15 20:11:11
回答 1查看 106关注 0票数 3

基本上,我希望用staticmethods创建一个“模板”类型对象,然后创建一个新对象,该对象继承自它,但是使用functools.partial使用父方法,其中使用子对象的参数。子参数的名称与父方法的参数相同。由此产生的范例如下:

代码语言:javascript
复制
class Naked:

    @staticmethod        
    def echo1(foo):
        return f"echo1: {foo}"

    @staticmethod        
    def echo2(bar, bla):
        return f"echo2: {bar}, {bla}"

class Clothed(Naked):
    def __init__(self, *args, **kwargs):
        for arg in args:
            setattr(self, arg, arg)

        for k,v in kwargs.items():
            setattr(self, k, v)

a = Clothed(foo = "Hello", bar = "World")
a.echo1 == "echo1: Hello"
a.echo2("wsup?") == "echo2: World, wsup?"

下面是一次不起作用的尝试:

代码语言:javascript
复制
from inspect import signature
from functools import partial
class Meta(type):
    def __init__(cls, name, bases, attrs):
         funcs = (k for k,v in attrs.items() if callable(v) and k not in dir(type)) #this doesn't work...
         for func in funcs:
            args = signature(func).keys() #function argument names
            newargs = {arg:getattr(self, arg, None) for arg in args} #create dictionary with val from instance, how is this possible, no self here?
            attrs[func] = partial(func,newargs)
        return type.__init__(cls, name, bases, attrs)  

class Naked(metaclass=Meta):

    @staticmethod        
    def echo1(foo):
        return f"echo1: {foo}"

    @staticmethod        
    def echo2(bar, bla):
        return f"echo2: {bar}, {bla}"

class Clothed(Naked):
    def __init__(self, *args, **kwargs):
        for arg in args:
            setattr(self, arg, arg)

        for k,v in kwargs.items():
            setattr(self, k, v)
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-05-15 21:50:46

我不知道如何使用元类来实现这一点,但是这里有一个可能的解决方案,它使用的是mixin类。你也许能用上这样的东西。

代码语言:javascript
复制
from inspect import signature
from functools import partialmethod, partial

class Naked:

    @staticmethod        
    def echo1(foo):
        return f"echo1: {foo}"

    @staticmethod        
    def echo2(bla, bar):
        return f"echo2: {bar}, {bla}"

class PartialMixin:
    def __init__(self, **kwargs):
        methods = [m for m in dir(self) if callable(getattr(self, m)) and m not in dir(type)]
        for method_name in methods:
            method = getattr(self, method_name)
            method_kwargs = signature(method).parameters.keys()
            partial_kwargs = {k:kwargs[k] for k in kwargs if k in method_kwargs}
            new_method = partial(method, **partial_kwargs)
            # if the methods are not static, maybe functools.partialmethod should be used.
            setattr(self, method_name, new_method)

class Clothed(PartialMixin, Naked):
    pass

a = Clothed(foo = "Hello", bar = "World")
a.echo1() == "echo1: Hello"
a.echo2("wsup?") == "echo2: World, wsup?"
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50358462

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档