首页 \ 问答 \ Python魔术元类创建(Python magic meta class creation)

Python魔术元类创建(Python magic meta class creation)

基本上,我想创建一个带有staticmethods的“模板”类型对象,然后创建一个继承自它的新对象,但使用functools.partial使用父functools.partial ,使用子functools.partial的参数。 子参数的名称与父参数的参数相同。 由此产生的范例将是这样的:

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?"

这是一个不起作用的尝试:

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)

Basically, I want to create a "template" type-object with staticmethods and then create a new object that inherits from it but uses the parent's methods using functools.partial where the arguments of the child are used. The child's arguments have the same name as the arguments for the methods of the parent. The resulting paradigm would be something like this:

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?"

Here is an attempt that doesn't work:

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)

原文:https://stackoverflow.com/questions/50358462
更新时间:2022-12-05 21:12

最满意答案

结果可以用caliburn完成绑定(参见本讨论)

<xcdg:DataGridControl ItemsSource="{Binding Contracts}" AutoCreateColumns="False">
    <xcdg:DataGridControl.Resources>
        <Style TargetType="{x:Type xcdg:DataCell}">
            <Setter Property="cal:Message.Attach" Value="[Event PreviewMouseDoubleClick] = [Action OpenContract($this)]" />
        </Style>
    </xcdg:DataGridControl.Resources>
    <xcdg:DataGridControl.View>
        <xcdg:TableView AllowColumnChooser="True" ShowFixedColumnSplitter="False" AllowRowResize="False" ShowRowSelectorPane="False" UseDefaultHeadersFooters="False" ColumnStretchMode="Last">
            <xcdg:TableView.FixedHeaders>
                <DataTemplate>
                    <xcdg:ColumnManagerRow AllowColumnReorder="True" AllowSort="True" AllowColumnResize="True" AllowAutoFilter="False" />
                </DataTemplate>
            </xcdg:TableView.FixedHeaders>
        </xcdg:TableView>
    </xcdg:DataGridControl.View>
    <xcdg:DataGridControl.Columns>
        <xcdg:Column FieldName="Name" Title="Name"></xcdg:Column>
        <xcdg:Column FieldName="CustomerName" Title="Customer"></xcdg:Column>
    </xcdg:DataGridControl.Columns>
</xcdg:DataGridControl>

Turns out the binding can be done with caliburn (see this discussion):

<xcdg:DataGridControl ItemsSource="{Binding Contracts}" AutoCreateColumns="False">
    <xcdg:DataGridControl.Resources>
        <Style TargetType="{x:Type xcdg:DataCell}">
            <Setter Property="cal:Message.Attach" Value="[Event PreviewMouseDoubleClick] = [Action OpenContract($this)]" />
        </Style>
    </xcdg:DataGridControl.Resources>
    <xcdg:DataGridControl.View>
        <xcdg:TableView AllowColumnChooser="True" ShowFixedColumnSplitter="False" AllowRowResize="False" ShowRowSelectorPane="False" UseDefaultHeadersFooters="False" ColumnStretchMode="Last">
            <xcdg:TableView.FixedHeaders>
                <DataTemplate>
                    <xcdg:ColumnManagerRow AllowColumnReorder="True" AllowSort="True" AllowColumnResize="True" AllowAutoFilter="False" />
                </DataTemplate>
            </xcdg:TableView.FixedHeaders>
        </xcdg:TableView>
    </xcdg:DataGridControl.View>
    <xcdg:DataGridControl.Columns>
        <xcdg:Column FieldName="Name" Title="Name"></xcdg:Column>
        <xcdg:Column FieldName="CustomerName" Title="Customer"></xcdg:Column>
    </xcdg:DataGridControl.Columns>
</xcdg:DataGridControl>

相关问答

更多
  • Caliburn.Micro无法处理这些情况。 您唯一的选择是: 叉Caliburn.Micro源并自行修复。 删除Caliburn.Micro并使用不同的MVVM框架。 This does indeed not go with built-in features of Caliburn.Micro. Instead of changing the internals of the framework which was suggested by @Keith, I just wired up the bu ...
  • 我使用Message cal:Message.Attach =“[Event Loaded] = [Action LoadReport($ this)]”这就是我需要的一切 I use Message cal:Message.Attach="[Event Loaded] = [Action LoadReport($this)]" and that is all I need
  • 问题1:如何绑定书籍? 没有显示图书项目...为什么? 问题在于您没有在用户控件构造函数中初始化您的数据源。 你可以使用下面的代码: public DragDropView() { this.InitializeComponent(); categoryCollectionViewSource.Source = new SampleData().GetCategoryDataSource(); bookCollectionViewSource.Source = new SampleD ...
  • 发现问题了! 我在包含Pivot的Grid中设置了一个DataContext,覆盖了ViewModel的约定DataContext。 我删除了它并且工作得很完美。 因此,您可以在指挥中使用任何POCO。 Found the problem! I was setting a DataContext in the Grid that contains the Pivot, overwriting the convention DataContext which is the ViewModel. I delet ...
  • 你应该使用User_Name。 You should use User_Name.
  • 结果可以用caliburn完成绑定(参见本讨论) :