1

我对 python 还是很陌生,这可能是那些(愚蠢的)无聊问题之一。但是,任何帮助将不胜感激。我正在编写一些涉及许多变量的程序,并且我决定使用一个类来封装所有变量(希望随着时间的推移让我更容易“阅读”),但它并没有像我想象的那样工作。因此,事不宜迟,这里是抓住要点的课程的一部分。

import numpy as np

class variable:
    def __init__(self, length):
        self.length = length # time length`
    def state_dynamic(self):
        length = self.length
        return np.zeros((2, np.size(length)))
    def state_static(self):
        length = self.length
        return np.zeros((2, np.size(length)))        
    def control_dynamic(self):
        length = self.length
        return np.zeros((2, np.size(length)))        
    def control_static(self):
        length = self.length
        return np.zeros((2, np.size(length)))
    def scheduling(self):
        length = self.length
        return np.zeros(np.size(length))
    def disturbance(self):
        length = self.length
        dummy = np.random.normal(0., 0.1, np.size(length))
        for i in range(20):
            dummy[i+40] = np.random.normal(0., 0.01) + 1.
        dummy[80:100] = 0.
        return dummy

我也试过这个:

import numpy as np

class variable:
    def __init__(self, type_1, type_2, length):
        self.type_1 = type_1 # belongs to set {state, control, scheduling, disturbance}
        self.type_2 = type_2 # belongs to set {static, dynamic, none}
        self.length = length # time length
    def type_v(self):
        type_1 = self.type_1
        type_2 = self.type_2
        length = self.length
        if type_1 == 'state' and type_2 == 'dynamic':
            return np.zeros((2, np.size(length)))
        elif type_1 == 'state' and type_2 == 'static':
            return np.zeros((2, np.size(length)))
        elif type_1 == 'control' and type_2 == 'dynamic':
            return np.zeros((2, np.size(length)))
        elif type_1 == 'control' and type_2 == 'static':
            return np.zeros((2, np.size(length)))
        elif type_1 == 'scheduling' and type_2 == 'none':
            return np.zeros(np.size(length))        
        elif type_1 == 'disturbance' and type_2 == 'none':
            dummy = np.random.normal(0., 0.1, np.size(length))
            for i in range(20):
            dummy[i+40] = np.random.normal(0., 0.01) + 1.
            dummy[80:100] = 0.
            return dummy

现在,使用第一个(第二个类的结果也相同),当我写以下内容时,说:

In [2]: time = np.linspace(0,10,100)

In [5]: v = variable(time)

In [6]: v1 = v.state_dynamic

In [7]: v1.size
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
/home/<ipython-input-7-e6a5d17aeb75> in <module>()
----> 1 v1.size

AttributeError: 'function' object has no attribute 'size'

In [8]: v2 = variable(np.size(time)).state_dynamic

In [9]: v2
Out[9]: <bound method variable.state_dynamic of <__main__.variable instance at 0x3ad0a28>>

In [10]: v1[0,0]
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
/home/<ipython-input-10-092bc2b9f982> in <module>()
----> 1 v1[0,0]

TypeError: 'instancemethod' object has no attribute '__getitem__'

我希望通过写作

variable(length).state_dynamic

我会访问

np.zeros((2, np.size(length)))

无论如何,如果我做了一些完全愚蠢的事情,请告诉我:) 并随时提供任何建议。预先感谢您的时间和亲切的关注。最好的祝福。

编辑#1:

@小麦:

感谢您的快速回复和帮助:)

我目前正在尝试做的是以下内容。我必须绘制几个“变量”,例如状态、控制、辍学、调度和干扰。所有变量都取决于三个参数,即动态、静态和水平。此外,状态和控制是np.zeros((2, np.size(length))),辍学和调度是np.zeros(np.size(length))和干扰具有特定的形式(见上文)。最初,我在脚本中声明了它们,列表很长而且看起来很丑。我使用这些变量来存储所考虑的动力系统的响应并绘制它们。我不知道这是否是这样做的好方法,如果您有任何建议,请分享。

再次感谢您的帮助。

4

2 回答 2

5

你的意思是你想要命名访问一堆状态信息?类变量的普通 python 习惯用法如下所示:

class Variable(object):
   def __init__ (self, state_dynamic, state_static, control_static, control_dynamic, scheduling):
      self.state_dynamic = state_dynamic
      self.state_static = state_static
      self.control_static = control_static
      self.control_dynamic = control_dynamic
      self.scheduling = control_dynamic

这实际上创建了一个带有命名字段的存储桶,这些字段保存您通过构造函数输入的值。您还可以使用namedtuple工厂类创建轻量级数据类,这样可以避免一些样板。

另一个可能适用的 python 习惯用法是使用@wheaties 答案中的@property装饰器。这基本上伪装了一个函数调用,使其看起来像一个字段。如果您正在做的事情可以简化为功能基础,那将是有道理的。这是这个想法的一个例子(不是基于你的问题集,因为我不确定我用所有这些相同的变量详细了解你在做什么)——在这种情况下,我正在制作一个方便的包装器来拉存储在 python 编号中但确实构成位字段的各个标志:

class Bits(object):
   def __init__(self, integer):
      self.Integer = integer # pretend this is an integer between 0 and 8 representing 4 flags

   @property 
   def locked(self):
      # low bit = locked
      return self.Integer & 1 == 1

   @property
   def available(self):
     return self.Integer & 2 == 2

   @property
   def running_out_of_made_up_names(self):
     return self.Integer & 4 == 4

   @property
   def really_desperate_now(self):
     return self.Integer & 8 == 8

 example = Bits(7)
 print example.locked
 # True
 print example.really_desperate_now
 # False
于 2013-07-17T04:13:29.470 回答
1

Python 中的方法是一个函数。如果要从成员函数中获取值,则必须以(). 也就是说,一些重构可能有助于消除样板文件并减少您头脑中的问题集大小。我建议将 a@property用于其中一些事情,并结合轻微的重构

class variable:
    def __init__(self, length):
    self.length = length # time length`

@property
def state_dynamic(self):
    return self.np_length    
@property
def state_static(self):
    return self.np_length
@property
def control_dynamic(self):
    return self.np_length
@property
def control_static(self):
    return self.np_length
@property
def scheduling(self):
    return self.np_length
@property
def np_length(self):
    return np.zeros(2, np.size(self.length))

这样您就可以像使用之前尝试过的成员变量一样使用这些函数:

var = variable(length).state_dynamic

我无法从这一切中看出所有这些变量之间的区别是什么?我没有看到一个。您是否假设您必须按顺序访问它们?如果是这样,那就是糟糕的设计和问题。永远不要做出这样的假设。

于 2013-07-17T03:14:33.517 回答