Class factory to produce simple struct-like classes?

后端 未结 7 1428
盖世英雄少女心
盖世英雄少女心 2020-12-08 05:47

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

Person = Struct.new(:forname, :surname)
person1 = Person.new(\'John\', \'Do         


        
7条回答
  •  情歌与酒
    2020-12-08 06:13

    This is following up on Cide's answer (and probably only interesting for people who want to dig deeper).

    I experienced a problem using Cide's updated definition of Struct(), the one using __slots__. The problem is that instances of returned classes have read-only attributes:

    >>> MS = Struct('forename','lastname')
    >>> m=MS()
    >>> m.forename='Jack'
    Traceback (most recent call last):
      File "", line 1, in 
    AttributeError: 'MyStruct' object attribute 'forename' is read-only
    

    Seems that __slots__ is blocking instance-level attributes when there are class attributes of same names. I've tried to overcome this by providing an __init__ method, so instance attributes can be set at object creation time:

    def Struct1(*args, **kwargs):
        def init(self):
            for k,v in kwargs.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()})
    

    As a net effect the constructed class only sees the __init__ method and the __slots__ member, which is working as desired:

    >>> MS1 = Struct1('forename','lastname')
    >>> m=MS1()
    >>> m.forename='Jack'
    >>> m.forename
    'Jack'
    

提交回复
热议问题