2013-06-17 3 views
2

Я создал функцию is_sequence (ARG) в классе degree_day (osv.osv)NameError: глобальное имя 'is_sequence' не определен

Когда я вызываю эту функцию из записи функции система генерирует ошибку:

NameError: глобальное имя «is_sequence» не определен

Я не понимаю, почему система не находит эта функция.

Client Traceback (most recent call last): 
    File "C:\Program Files (x86)\OpenERP 7.0-20130520-231036\Server\server\openerp\addons\web\http.py", line 204, in dispatch 
    File "C:\Program Files (x86)\OpenERP 7.0-20130520-231036\Server\server\openerp\addons\web\controllers\main.py", line 1130, in call_kw 
    File "C:\Program Files (x86)\OpenERP 7.0-20130520-231036\Server\server\openerp\addons\web\controllers\main.py", line 1122, in _call_kw 
    File "C:\Program Files (x86)\OpenERP 7.0-20130520-231036\Server\server\openerp\addons\web\session.py", line 42, in proxy 
    File "C:\Program Files (x86)\OpenERP 7.0-20130520-231036\Server\server\openerp\addons\web\session.py", line 30, in proxy_method 
    File "C:\Program Files (x86)\OpenERP 7.0-20130520-231036\Server\server\openerp\addons\web\session.py", line 103, in send 


Server Traceback (most recent call last): 
    File "C:\Program Files (x86)\OpenERP 7.0-20130520-231036\Server\server\openerp\addons\web\session.py", line 89, in send 
    File "C:\Program Files (x86)\OpenERP 7.0-20130520-231036\Server\server\.\openerp\netsvc.py", line 292, in dispatch_rpc 
    File "C:\Program Files (x86)\OpenERP 7.0-20130520-231036\Server\server\.\openerp\service\web_services.py", line 626, in dispatch 
    File "C:\Program Files (x86)\OpenERP 7.0-20130520-231036\Server\server\.\openerp\osv\osv.py", line 188, in execute_kw 
    File "C:\Program Files (x86)\OpenERP 7.0-20130520-231036\Server\server\.\openerp\osv\osv.py", line 131, in wrapper 
    File "C:\Program Files (x86)\OpenERP 7.0-20130520-231036\Server\server\.\openerp\osv\osv.py", line 197, in execute 
    File "C:\Program Files (x86)\OpenERP 7.0-20130520-231036\Server\server\.\openerp\osv\osv.py", line 185, in execute_cr 
    File "C:\Program Files (x86)\OpenERP 7.0-20130520-231036\Server\server\openerp\addons\degree_day\degree_day.py", line 187, in correct_future_degree_day 
    File "C:\Program Files (x86)\OpenERP 7.0-20130520-231036\Server\server\openerp\addons\degree_day\degree_day.py", line 79, in write 
NameError: global name 'is_sequence' is not defined 

degree_day.py

from openerp.osv import osv, fields 
from dateutil.parser import * 
from dateutil.tz import * 
from datetime import * 


class degree_day(osv.osv): 

    _name = "degree.day" 
    _order = "date" 
    _columns={ 
     'date': fields.date('Date'), 
     'high_temp': fields.integer('High Temp'), 
     'low_temp': fields.integer('Low Temp'), 
     'heat_degree_day': fields.integer('Heat Degree Day'), 
     'hw_degree_day': fields.integer('Hot Water Degree Day'), 
     'state': fields.selection([ 
      ('normal','Normal'), 
      ('initial_dd_adjust','Adjust Initial Degree Day') 
      ], 'Status', readonly=True, track_visibility='onchange', 
      help=' * The \'Normal\' status is used when a user is entering high and low temps and degree day values are readonly \ 
      \n* The \'Adjust Initial Degree Day\' status is used when a user is manually adjusting the first degree day records degree day values.'), 
     'debug':fields.text('Debug text'), 
     'initial_dd_record': fields.boolean("First DD Record"), 
    } 

    _defaults = { 
     'state': lambda *a: 'normal', 
    } 

    def is_sequence(arg): 
      return (not hasattr(arg, "strip") and 
       hasattr(arg, "__getitem__") or 
       hasattr(arg, "__iter__")) 

    def write(self, cr, uid, ids, vals, context=None): 
     debug = '... ' 
     dd_recs = self.pool.get('degree.day') 

     # were degree.day records retrieved? 
     if dd_recs: 
      debug += " dd_recs not null:" 

      # initial dd recs have dd values entered manually 
      # since there is no Day Before to draw from 
      init_dd_rec = dd_recs.read(cr, uid, ids, ["initial_dd_record"]) 
      debug += "initial_dd_record="+str(init_dd_rec)+":" 

      # sometimes this comes thorugh as a list and sometimes as single 
      # convert to single if list 
      if is_sequence(init_dd_rec): 
       one_init_dd_rec = init_dd_rec[0] 
      else: 
       one_init_dd_rec = init_dd_rec 

      # skip readonly override code if initial_dd_record is true 
      # as all fields are readonly=False in this case 
      if not one_init_dd_rec: 
       debug += " not initial dd rec:" 

       # if high_temp not present, add it 
       if not vals.has_key('high_temp'): 
        debug += " no high_temp:" 
        vals['high_temp'] = dd_recs.read(cr, uid, ids, ["high_temp"])[0]['high_temp'] 

       # if low_temp not present, add it 
       if not vals.has_key('low_temp'): 
        debug += " no low_temp:" 
        vals['low_temp'] = dd_recs.read(cr, uid, ids, ["low_temp"])[0]['low_temp'] 

       vals['date'] = dd_recs.read(cr, uid, ids, ["date"])[0]['date'] 
       debug += " vals['date']="+vals['date']+":" 
       debug += " dd_recs.read(cr, uid, ids, ['date'])=" +str(dd_recs.read(cr, uid, ids, ['date']))+":" 

       # date seems to be stored as a string, so need to convert it before 
       # using it to find yesterdays date 
       adate = parse(vals['date']) 
       day_before = adate - timedelta(days=1) 
       db_ids = dd_recs.search(cr, uid, [("date", "=", day_before)]) 

       # is there a record for yesterday? 
       if db_ids: 
        debug += " ids not null:" 
        last_hdd = dd_recs.read(cr, uid, db_ids[0], ['heat_degree_day'])['heat_degree_day'] 
        debug += " last_hdd="+str(last_hdd)+":" 
        last_hwdd = dd_recs.read(cr, uid, db_ids[0], ['hw_degree_day'])['hw_degree_day'] 
        high_temp = vals['high_temp'] 
        low_temp = vals['low_temp'] 
        a = 65 - ((high_temp + low_temp)/2) 
        if a < 0: 
         a = 0 
        vals['heat_degree_day'] = a + last_hdd 
        vals['hw_degree_day'] = a + 5 + last_hwdd 

     vals['debug'] = debug 

     return super(degree_day, self).write(cr, uid, ids, vals, context=context) 



    def create(self, cr, uid, vals, context=None): 
     debug = '... ' 
     if vals.has_key('high_temp') and vals.has_key('low_temp'): 
      adate = parse(vals['date']) 
      day_before = adate - timedelta(days=1) 
      dd_recs = self.pool.get('degree.day') 
      # were any degree.day records retrieved? 
      if dd_recs: 
       debug += " dd_recs not null:" 
       ids = dd_recs.search(cr, uid, [("date", "=", day_before)]) 
       # is there a record for yesterday? 
       if ids: 
        debug += " ids not null:" 
        last_hdd = dd_recs.read(cr, uid, ids[0], ["heat_degree_day"]) 
        last_hwdd = dd_recs.read(cr, uid, ids[0], ["hw_degree_day"]) 
        high_temp = vals['high_temp'] 
        low_temp = vals['low_temp'] 
        a = 65 - ((high_temp + low_temp)/2) 
        if a < 0: 
         a = 0 
        vals['heat_degree_day'] = a + last_hdd['heat_degree_day'] 
        vals['hw_degree_day'] = a + 5 + last_hwdd['hw_degree_day'] 

     vals['debug'] = debug 
     return super(degree_day, self).create(cr, uid, vals, context=context) 



    def correct_future_degree_day(self, cr, uid, ids, heat_degree_day, hw_degree_day, date, debug, context=None): 
     """ when a degree days record is changed, all following records must be corrected 
     @param high_temp: The day's high temperature 
     @param low_temp: The day's low temperature 
     """ 
     v={} 
     debug = "... " 

     dd_recs = self.pool.get('degree.day') 
     if dd_recs: 
      debug += " dd_recs not null:" 
      ids = dd_recs.search(cr, uid, [("date", ">=", date)], 0, None, "date") 
      # are there records after this date? 
      if ids: 
       debug += " future records found:" 
       running_hdd = heat_degree_day 
       running_hwdd = hw_degree_day 
       # cycle through each record recalculating degree day values 
       for i in ids: 
        debug += "loop " + str(i) + ":" 
        low_temp = dd_recs.read(cr, uid, i, ["low_temp"])["low_temp"] 
        high_temp = dd_recs.read(cr, uid, i, ["high_temp"])["high_temp"] 
        # degree day calculation 
        a = 65 - ((high_temp + low_temp)/2) 
        if a < 0: 
         debug += " a<0:" 
         a = 0 
        running_hdd += a 
        running_hwdd += a + 5 
        update_dd = {"heat_degree_day":running_hdd, "hw_degree_day":running_hwdd} 
        dd_recs.write(cr, uid, i, update_dd, context=None) 
        debug += " done:" 

     v['debug'] = debug 
     return {'value':v} 

degree_day_view.xml

<?xml version="1.0" encoding="utf-8"?> 
<openerp> 
    <data> 
     <record id="degree_day_tree" model="ir.ui.view"> 
      <field name="name">degree.day.tree</field> 
      <field name="priority" eval="1"/>   
      <field name="model">degree.day</field> 
      <field name="arch" type="xml"> 
       <tree string="Degree Day List"> 
        <field name="date" /> 
        <field name="high_temp" /> 
        <field name="low_temp" /> 
        <field name="heat_degree_day" /> 
        <field name="hw_degree_day" /> 
        <field name="state" invisible="True" /> 
        <field name="debug" /> 
       </tree> 
      </field> 
     </record> 

     <record id="degree_day_form" model="ir.ui.view"> 
      <field name="name">degree.day.form</field> 
      <field name="model">degree.day</field> 
      <field name="priority" eval="2"/>   
      <field name="arch" type="xml"> 
       <form string="Degree Day" version="7.0"> 
        <sheet string="Degree Day"> 
         <h1>Day <field name="date" class="oe_inline"/></h1> 
         <group> 
          <field name="low_temp" readonly="False"/> 
          <field name="high_temp" readonly="False"/> 
         </group> 
         <group> 
          <field name="heat_degree_day" attrs="{'readonly': [('initial_dd_record','=',False)]}" on_change="correct_future_degree_day(heat_degree_day, hw_degree_day, date, debug)"/> 
          <field name="hw_degree_day" attrs="{'readonly': [('initial_dd_record','=',False)]}" on_change="correct_future_degree_day(heat_degree_day, hw_degree_day, date, debug)" /> 
         </group> 
         <group> 
          <field name="initial_dd_record" /> 
         </group> 
         <field name="state" invisible="True" /> 
         <field name="debug" /> 
        </sheet> 
       </form> 
      </field> 
     </record> 

     <record id="show_degree_day" model="ir.actions.act_window"> 
      <field name="name">Degree Day</field> 
      <field name="view_id" ref="degree_day_tree" /> 
      <field name="res_model">degree.day</field> 
      <field name="view_type">form</field> 
      <field name="view_mode">tree,form</field> 
     </record> 

     <menuitem id="degree_day_menu" name="Degree Day"/> 
     <menuitem id="degree_day_main_menu" parent="degree_day_menu" name="Degree Day Menu" /> 

     <menuitem name="Degree Day List" id="menu_degree_day_list" 
      parent="degree_day_main_menu" action="show_degree_day"/> 


    </data> 

</openerp> 

ответ

1

Если вы вызываете функцию, не привязывая ее к экземпляру класса degree_day, вам необходимо вызвать его с помощью параметра degree_day.is_sequence и передать экземпляр degree_day в качестве первого аргумента функции.

Однако не имеет смысла ограничивать сферу применения функции классом, не делая его методом экземпляра или статическим методом. Если вам нужно сделать его статическим методом, украсьте его «@staticmethod». Если вам нужно, чтобы это был метод экземпляра, определите его как другие методы ниже, передав self в качестве первого аргумента.

 
So the two options are 
1) static method 

@staticmethod 
def is_sequence(arg): 
    ... 
 
2) Instance method 

def is_sequence(self, arg): 
    ... 
 

В первом случае вы можете вызвать его с помощью степени_day.is_sequence. Во втором случае, поскольку вы вызываете из другого метода, вы можете вызвать его с помощью self.is_sequence.

+0

3-й вариант в том, что предложенный falsetru, выбраться из класса! –

+0

Спасибо, сэр. Мне нужно немного изучить, почему методы в одном классе должны быть квалифицированы. Я привык только к тому, чтобы квалифицировать вызовы методов вне класса ... – Adam

+0

Всякий раз, когда вы определяете что-либо внутри определения класса, к нему должен быть обращен экземпляр. Подробнее о правилах определения области охвата можно узнать по адресу http://docs.python.org/2/tutorial/classes.html#random-remarks. Таким образом, независимо от того, обращаетесь ли вы к нему из метода или извне, не имеет значения для интерпретатора python. Его по дизайну, к которому должен обращаться любой атрибут класса с связанным экземпляром (или именем класса). Это помогает с читабельностью кода. На первый взгляд читатель может понять, что любая переменная, называемая переменной экземпляра, а не локальной/глобальной переменной! –

2

Вызов is_sequence(..), как self.is_sequence(..) и сделать is_sequence как STATICMETHOD.

ИЛИ

Сделать is_sequence функции. (Убирайтесь из класса).

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