Py学习  »  Python

python:向实例添加属性,使其出现在类中

Post169 • 5 年前 • 1335 次点击  

为了在python中创建类似于matlab的struct的东西,我想创建一个类,当它的一个实例被赋予一个新的属性时,这个类作为一个整体还没有,这个类被自动声明为有一个该名称的属性(但是dyn值)。

例如,如果我定义了类 color 以这种方式,但是没有属性可以开始,然后我可以执行以下操作:

>> red = color()
>> blue = color()
>> blue.temperature
   AttributeError: type object 'color' has no attribute 'temperature'
>> red.temperature = 'hot'
>> blue.temperature
   blue.temperature = ''
>> blue.temperature = 'cool'

有没有一种方法可以破解添加另一个属性并向其添加类似于 cls.x = '' x 是添加到实例的属性名称的变量?

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/41033
 
1335 次点击  
文章 [ 2 ]  |  最新文章 5 年前
hpaulj
Reply   •   1 楼
hpaulj    5 年前

以八度为例 https://octave.org/doc/v4.4.1/Structure-Arrays.html

生成结构数组:

>> x(1).a = "string1";
>> x(2).a = "string2";
>> x(1).b = 1;
>> x(2).b = 2;
>>
>> x
x =

  1x2 struct array containing the fields:

    a
    b

如果向一个条目添加字段,则会为另一个条目添加或定义默认值:

>> x(1).c = 'red'
x =

  1x2 struct array containing the fields:

    a
    b
    c

>> x(2)
ans =

  scalar structure containing the fields:

    a = string2
    b =  2
    c = [](0x0)

>> save -7 struct1.mat x

麻木的

In [549]: dat = io.loadmat('struct1.mat')
In [550]: dat
Out[550]: 
{'__header__': b'MATLAB 5.0 MAT-file, written by Octave 4.2.2, 2019-02-09 18:42:35 UTC',
 '__version__': '1.0',
 '__globals__': [],
 'x': ...

In [551]: dat['x']
Out[551]: 
array([[(array(['string1'], dtype='<U7'), array([[1.]]), array(['red'], dtype='<U3')),
        (array(['string2'], dtype='<U7'), array([[2.]]), array([], shape=(0, 0), dtype=float64))]],
      dtype=[('a', 'O'), ('b', 'O'), ('c', 'O')])
In [552]: _.shape
Out[552]: (1, 2)

该结构已转换为结构化的numpy数组,具有相同的 shape 作为八度音阶 size(x) . 每个struct字段都是 dat .

与Octave/Matlab相比,我们不能在 dat['x'] 就位。我认为在 import numpy.lib.recfunctions as rf 它可以添加一个字段,对未定义的值使用各种形式的屏蔽或默认值,但这将生成一个新数组。有了一些工作,我可以从头开始。

In [560]: x1 = rf.append_fields(x, 'd', [10.0])
In [561]: x1
Out[561]: 
masked_array(data=[(array(['string1'], dtype='<U7'), array([[1.]]), array(['red'], dtype='<U3'), 10.0),
                   (array(['string2'], dtype='<U7'), array([[2.]]), array([], shape=(0, 0), dtype=float64), --)],
             mask=[(False, False, False, False),
                   (False, False, False,  True)],
       fill_value=('?', '?', '?', 1.e+20),
            dtype=[('a', 'O'), ('b', 'O'), ('c', 'O'), ('d', '<f8')])
In [562]: x1['d']
Out[562]: 
masked_array(data=[10.0, --],
             mask=[False,  True],
       fill_value=1e+20)

这种操作不适合python类系统。类通常不会跟踪其实例。一旦定义了一个类,它通常不会被修改。可以维护实例列表,也可以向现有类添加方法,但这不是常见的做法。

Joran Beasley
Reply   •   2 楼
Joran Beasley    5 年前

这个 setattr 方法

x = "temperature"
setattr(red,x,"HOT")

我想是你想要的

但也许你想要的是 __setattr__ __getattr__ 颜色类的方法

class color:
     attrs = {}
     def __getattr__(self,item):
         if item in self.attrs:
            return self.attrs[item]
         return ""
     def __setattr__(self,attr,value):
         self.attrs[attr] = value

c = color()
print(repr(c.hello))
c.hello = 5
print(repr(c.hello))
print(repr(c.temperature))
x = 'temperature'
setattr(c,x,"HOT")
print(repr(c.temperature))