类工厂生产简单的类结构类? [英] Class factory to produce simple struct-like classes?

查看:25
本文介绍了类工厂生产简单的类结构类?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在研究 Ruby 时,我遇到了这个来创建一个简单的类似 Struct 的类:

Person = Struct.new(:forname, :surname)person1 = Person.new('John', 'Doe')puts person1 #<struct Person forname="John", surname="Doe">

这给我提出了一些 Python 问题.我已经用 Python 编写了这个机制的 [非常] 基本克隆:

def 结构(*args):新结构类:def __init__(self):对于 args 中的 arg:self.__dict__[arg] = 无返回新结构>>>Person = Struct('名字', '姓氏')>>>人 1 = 人()>>>人 2 = 人()>>>person1.forename, person1.surname = 'John','Doe'>>>person2.forename, person2.surname = 'Foo','Bar'>>>person1.forename'约翰'>>>person2.forename'福'

  1. Python 中是否已经有类似的机制来处理这个问题?(我通常只使用字典).

  2. 我如何获得 Struct() 函数来创建正确的 __init__() 参数.(在这种情况下,如果可能,我想执行 person1 = Person('John', 'Doe') 命名参数:person1 = Person(surname='Doe', forename='John')

我很感兴趣,即使有更好的 Python 机制可以回答问题 2.

解决方案

ThomasH 变体的更新:

def Struct(*args, **kwargs):def init(self, *iargs, **ikwargs):对于 kwargs.items() 中的 k,v:setattr(self, k, v)对于范围内的 i(len(iargs)):setattr(self, args[i], iargs[i])对于 ikwargs.items() 中的 k,v:setattr(self, k, v)name = kwargs.pop("name", "MyStruct")kwargs.update(dict((k, None) for k in args))返回类型(名称,(对象,),{'__init__':init,'__slots__':kwargs.keys()})

这允许将参数(和命名参数)传递给 __init__()(没有任何验证 - 看起来很粗糙):

<预><代码>>>>Person = Struct('fname', 'age')>>>person1 = Person('凯文', 25)>>>person2 = Person(age=42, fname='Terry')>>>person1.age += 10>>>person2.age -= 10>>>person1.fname, person1.age, person2.fname, person2.age(凯文",35,特里",32)>>>

更新

看看如何 namedtuple()collections.py 中执行此操作一>.该类被创建并扩展为字符串并进行评估.还支持酸洗等等.

While investigating Ruby I came across this to create a simple Struct-like class:

Person = Struct.new(:forname, :surname)
person1 = Person.new('John', 'Doe')
puts person1  #<struct Person forname="John", surname="Doe">

Which raised a few Python questions for me. I have written a [VERY] basic clone of this mechanism in Python:

def Struct(*args):
    class NewStruct:
        def __init__(self):
            for arg in args:
                self.__dict__[arg] = None

    return NewStruct

>>> Person = Struct('forename', 'surname')
>>> person1 = Person()
>>> person2 = Person()
>>> person1.forename, person1.surname = 'John','Doe'
>>> person2.forename, person2.surname = 'Foo','Bar'
>>> person1.forename
'John'
>>> person2.forename
'Foo'

  1. Is there already a similar mechanism in Python to handle this? (I usually just use dictionaries).

  2. How would I get the Struct() function to create the correct __init__() arguments. (in this case I would like to perform person1 = Person('John', 'Doe') Named Arguments if possible: person1 = Person(surname='Doe', forename='John')

I Would like, as a matter of interest, to have Question 2 answered even if there is a better Python mechanism to do this.

解决方案

An update of ThomasH's variant:

def Struct(*args, **kwargs):
    def init(self, *iargs, **ikwargs):
        for k,v in kwargs.items():
            setattr(self, k, v)
        for i in range(len(iargs)):
            setattr(self, args[i], iargs[i])
        for k,v in ikwargs.items():
            setattr(self, k, v)

    name = kwargs.pop("name", "MyStruct")
    kwargs.update(dict((k, None) for k in args))
    return type(name, (object,), {'__init__': init, '__slots__': kwargs.keys()})

This allows parameters (and named parameters) passed into __init__() (without any validation - seems crude):

>>> Person = Struct('fname', 'age')
>>> person1 = Person('Kevin', 25)
>>> person2 = Person(age=42, fname='Terry')
>>> person1.age += 10
>>> person2.age -= 10
>>> person1.fname, person1.age, person2.fname, person2.age
('Kevin', 35, 'Terry', 32)
>>> 

Update

Having a look into how namedtuple() does this in collections.py. The class is created and expanded as a string and evaluated. Also has support for pickling and so on, etc.

这篇关于类工厂生产简单的类结构类?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆