色氨酸超载(或者,简单的python类初始化不起作用)

时间:2014-11-28 06:32:49

标签: python

Python 3.4

所以也许这是火鸡的消化,或者也许是我缺乏python魔法,但是我的简单想法初始化一个类的实例,其中几个成员都设置为None似乎不起作用。即:

dataA.txt

# layername   purpose    stmLay  stmDat
topside       copper     3       5
levelA        trace5     6       8

shouldWork.py

#!C:/Python34

import sys
import re

class LayerDataInn:
 def __init__( self, layername, purpose, stmLay, stmDat):
   self.layername = layername
   self.purpose   = purpose
   self.stmLay    = stmLay
   self.stmDat    = stmDat
 def __init__( self, list_data):
   self.layername = list_data[0]
   self.purpose   = list_data[1]
   self.stmLay    = list_data[2]
   self.stmDat    = list_data[3]
 def display( self):
   print("layername"
         " purpose:",  self.purpose, \
         " stmLay:",   self.stmLay, \
         " stmDat:",   self.stmDat )
 def toList( self):
   return [ self.layername, \
            self.purpose, \
            self.stmLay, \
            self.stmDat ]

class LayerDataOut:
 def __init__( self, layername, purpose, stmLay, stmDat, maskColor):
   self.layername = layername
   self.purpose   = purpose
   self.stmLay    = stmLay
   self.stmDat    = stmDat
   self.maskColor = maskColor
 def __init__( self, list_data):
   self.layername = list_data[0]
   self.purpose   = list_data[1]
   self.stmLay    = list_data[2]
   self.stmDat    = list_data[3]
   self.maskColor = list_data[4]
 def display( self):
   print("layername"
         " purpose:",   self.purpose, \
         " stmLay:",    self.stmLay, \
         " stmDat:",    self.stmDat, \
         " maskColor:", self.maskColor )
 def toList( self):
   return [ self.layername, \
            self.purpose, \
            self.stmLay, \
            self.stmDat, \
            self.maskColor ]

class LayerDataOutOut( object):
 def __init__( self):
   self.layername = None
   self.purpose   = None
   self.stmLay    = None
   self.stmDat    = None
   self.maskColor = None
 def insert( self, *args):
   if( len( args) == 2):
     self.layername = list_data[0]
     self.purpose   = list_data[1]
     self.stmLay    = list_data[2]
     self.stmDat    = list_data[3]
     self.maskColor = list_data[4]
   if( len( args) == 6):
     self.layername = layername
     self.purpose   = purpose
     self.stmLay    = stmLay
     self.stmDat    = stmDat
     self.maskColor = maskColor
 def display( self):
   print("layername",   self.layername, \
         " purpose:",   self.purpose, \
         " stmLay:",    self.stmLay, \
         " stmDat:",    self.stmDat, \
         " maskColor:", self.maskColor )
 def toList( self):
   return [ self.layername, \
            self.purpose, \
            self.stmLay, \
            self.stmDat, \
            self.maskColor ]

# read the file
list_layerInn = []
fn_layerInn = "dataA.txt"
with open( fn_layerInn) as fp_layerInn:
 for line in fp_layerInn:
   list_layerInn.append( LayerDataInn( line.split()))

# list out the file
for objLayerInn in list_layerInn:
 objLayerInn.display()

list_layerOut = []
for objLayerInn in list_layerInn:
 list_objLayerInn = objLayerInn.toList()
 list_objLayerInn.append("woohoo")
 list_layerOut.append( LayerDataOut( list_objLayerInn))

# list out the file
for objLayerOut in list_layerOut:
 objLayerOut.display()

list_layerOutOut = []
for objLayerInn in list_layerInn:
 objLayerOutOut = LayerDataOutOut()
 setattr( objLayerOutOut, layername, getattr( objLayerInn, layername))  # <-- dies here
 setattr( objLayerOutOut, purpose,   getattr( objLayerInn, purpose))
 setattr( objLayerOutOut, stmLay,    getattr( objLayerInn, stmLay))
 setattr( objLayerOutOut, stmDat,    getattr( objLayerInn, stmDat))
 setattr( objLayerOutOut, maskColor, "wheeee" )
 list_layerOutOut.append( objLayerOutOut)

# list out the file
for objLayerOutOut in list_layerOutOut:
 objLayerOutOut.display()

我希望LayerDataOutOut的 init 会添加值为None的成员,以便使用setattr进行及时更新。

这里的总体目标是能够实例化一个类的实例,其中所有成员都被占用并设置为None,只需简单地调用没有参数的类,如Java或C ++

TIA,

仍在学习史蒂夫

2 个答案:

答案 0 :(得分:1)

看看这一行:

setattr( objLayerOutOut, layername, getattr( objLayerInn, layername))

这是我收到的错误消息:

Traceback (most recent call last):
  File "shouldWork.py", line 109, in <module>
    setattr( objLayerOutOut, layername, getattr( objLayerInn, layername))
 dies here
NameError: name 'layername' is not defined

您收到此错误的原因是因为您告诉Python使用名为layername的内容,而Python假定该内容是变量名称。但是,您从未创建过一个名为layername的变量,因此Python会感到困惑并崩溃!

您可能打算使用字符串:

setattr( objLayerOutOut, 'layername', getattr( objLayerInn, 'layername'))

这不是特定于Python的事情 - 在Java / C ++中也会发生同样的事情。如果要在运行时动态访问某些值,通常需要将字段名称作为字符串提供。

或者更好的是,免除setattrgetattr,直接设置字段,就像Java一样:

objLayerOutOut.layername = objLayerInn.layername

这两种方法都可以修复您的代码。


作为旁注,你的代码不是100%Pythonic。以下是我注意到的一些事情:

  1. 不幸的是,Python并不支持方法重载。如果您声明了两个__init__方法,那么第一个方法将被第二个方法覆盖。相反,您通常会使用默认参数,或***参数解包运算符。例如:

    def foo(a, b, c, d=None):
        print(a, b, c, d)
    
    foo(1, 2, 3)
    
    my_list = [5, 6, 7]
    foo(*my_list, d = 42)
    
  2. 在Python中,按照惯例,每行按4个空格缩进。

  3. 如上所述,我们无需使用setattrgetattr - 只需直接设置字段即可。当我们想要访问的字段/方法的名称仅在运行时知道时,我们主要使用setattrgetattr - 它们基本上是元编程工具。

答案 1 :(得分:1)

setattr( objLayerOutOut, layername, getattr( objLayerInn, layername))

layernameobjLayerOutOutobjLayerInn上的属性,而不是一个变量,其内容代表您要设置的属性的名称。使用点符号!

objLayerOutOut.layername = objLayerInn.layername

与其他人相同。