2013-07-17 2 views
1

Я по-прежнему новичок в python, и это, вероятно, будет одним из тех (глупых) скучных вопросов. Тем не менее, любая помощь будет высоко оценена. Я программирую что-то, что включает в себя множество переменных, и я решил использовать класс для инкапсуляции всех переменных (надеюсь, упростить «чтение» для меня со временем), но он не работает, как я думал. Таким образом, без дальнейших церемоний здесь есть часть класса, который захватывает суть.Использование класса для определения нескольких переменных в 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))) 

Во всяком случае, если я сделал что-то совершенно дурацкий, пожалуйста, дайте мне знать :) и не стесняйтесь давать какие-либо советы. Заранее благодарю вас за ваше время и внимание. С наилучшими пожеланиями.

EDIT # 1:

@wheaties:

Спасибо за быстрый ответ и помочь :)

То, что я сейчас пытаюсь сделать следующее. Я должен построить несколько «переменных», например, состояние, контроль, отсева, планирование и нарушения. Все переменные зависят от трех параметров: динамического, статического и горизонтального. Кроме того, состояние и управление - np.zeros((2, np.size(length))), исключения и планирование - np.zeros(np.size(length)), а помехи имеют конкретную форму (см. Выше). Сначала я объявил их в скрипте, и список очень длинный и выглядит уродливым. Я использую эти переменные для хранения ответов рассмотренных динамических систем и их построения. Я не знаю, если это хороший способ сделать это, и если у вас есть какие-либо предложения, пожалуйста, поделитесь.

Еще раз спасибо за помощь.

+0

Я не думаю, что этот класс 'variable' правильно представляет понятие переменной. Во-первых, если 'v' является' переменной', то 'v.state_dynamic() не является v.state_dynamic()'. Любые изменения, внесенные в 'v.state_dynamic()', будут эффективно проигнорированы, так как при следующем доступе к 'v.state_dynamic()' вы получите новый массив. Почему бы просто не использовать фактические переменные? – user2357112

ответ

4

Вы хотите, чтобы именованный доступ к кучей информации о состоянии?Обычный питон идиом для переменного класса будет выглядеть следующим образом:

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, которая может применяться, заключается в использовании @property decorator, как в ответе @wheaties. Это в основном маскирует вызов функции, чтобы он выглядел как поле. Если то, что вы делаете, можно свести к функциональной основе, это имеет смысл. Это пример идеи (не основанный на вашей задаче, так как я не уверен, что я подробно расскажу о том, что вы делаете, со всеми этими идентичными переменными) - в этом случае я делаю удобную обертку для вытягивать отдельные флаги, что хранятся в нескольких питона, но на самом деле сделать битовое поле:

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 
+0

Привет и спасибо :) Я использовал вторую идиому. Тем не менее, я в конечном итоге не обрезал основной код много ... Я думаю, что я задал неправильный вопрос ... Не знаю, является ли раздел с комментариями подходящим местом, но, что это хороший способ организовать код, если многие переменные рассматриваемой системы должны быть построены? А именно, я имитирую Networked Control System и имею много переменных, которые мне нужно построить. Объявление всех переменных для построения в главном скрипте выглядит очень уродливо. Я думал, что, создав «переменные» класса, я бы обрезал код и делал свои имена в виде функций, например, переменной (состояние, динамический, горизонт = 2). – 605na

+0

Это нормально, чтобы реорганизовать вопрос как ответ на обратную связь - происходит все время. Возможно, вам захочется взглянуть на некоторые многолетние вопросы python, например http://stackoverflow.com/questions/36932/how-can-i-represent-an-enum-in-python и http://stackoverflow.com/questions/1849311/how-should-i-organiz-python-source-code Вы также можете посмотреть, можете ли вы более подробно подразделить проблему на более глубокую иерархию классов - количество дублирования в примере показывает, что то, что у вас есть как функции, может потребоваться быть экземплярами класса – theodox

+0

И - одно хорошее правило в pythonland: чем лучше код, тем короче и читабельнее. Если код кажется громоздким, это будет рефакторинг, ожидающий случиться :) – theodox

1

Метод в Python - это функция. Если вы хотите получить значение от функции-члена, вам нужно положить ее в (). Тем не менее, некоторые рефакторинги могут помочь устранить шаблон и уменьшить размер заданного размера в вашей голове. Я предложил бы использовать @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 

Что я не могу сказать из всего этого, в чем разница между всеми этими переменными? Я не вижу никого. Вы предполагаете, что вам нужно получить к ним доступ по порядку? Если это так, это плохой дизайн и проблема. Никогда не делайте этого предположения.

Смежные вопросы