【问题标题】:.startswith not working.startswith 不工作
【发布时间】:2011-03-29 16:02:55
【问题描述】:

在我的程序中,我有一个文件,然后我通读了 for 循环中的所有行,检查每一行的开头。然后将每一行添加为变量。其中有 40 多行,它们几乎都相同,但是其中一个 elif 语句不返回 true .startswith 不起作用。无论如何,这里是文件内容,基本上是一堆保存的信息 fN 将是我保存的变量,而 john 将是我想要的。所以这个方法就是这样做的,或者它应该是这样的

fN:john
fP:1
fE:father email
mN:mother name
mP:1
mE:mother email @ bomg.com
a:1233 adress lane
c:city
s:state
zC:1234534
hP:(1928)phone-1123
cP:1113333
eN:emergancy
eNu:number
c1N:cluubiie 1
c1G:1st
c1B:1-23-34
c2N:clubbie 2
c2G:grade 2
c2B:birth 2
c3N:clubb 3 
c3G:grade 3
c3B:birth 3

方法

def fillWindow(self,student):
    global fileDirectory
    location = os.path.join(fileDirectory, student + '.txt')
    file = open(location, 'r')

    for line in file.xreadlines():
        if line.startswith('fN'):
            fN = line.split(':')[1]
        elif line.startswith('fP'):
            fP = line.split(':')[1]
        elif line.startswith('fE'):
            fE = line.split(':')[1]
        elif line.startswith('mN'):
            mN = line.split(':')[1]
        elif line.startswith('mP'):
            mP = line.split(':')[1]
        elif line.startswith('mE'):
            mE = line.split(':')[1]
        elif line.startswith('a'):
            a = line.split(':')[1]
        elif line.startswith('c'):
            c = line.split(':')[1] 
        elif line.startswith('s'):
            s = line.split(':')[1]
        elif line.startswith('zC'):
            zC = line.split(':')[1]
        elif line.startswith('hP'):
            hP = line.split(':')[1]

这里永远不会返回 True,即使文件中有一行以 cP 开头

        elif line.startswith('cP'):
            cP = line.split(':')[1]
            print('True') 
        elif line.startswith('eN'):
            eN = line.split(':')[1]
        elif line.startswith('eNu'):
            eNu = line.split(':')[1]
        elif line.startswith('c1N'):
            c1N = line.split(':')[1] 
        elif line.startswith('c1G'):
            c1G = line.split(':')[1]
        elif line.startswith('c1B'):
            c1B = line.split(':')[1] 
        elif line.startswith('c2N'):
            c2N = line.split(':')[1] 
        elif line.startswith('c2G'):
            c2G = line.split(':')[1]
        elif line.startswith('c2B'):
            c2B = line.split(':')[1]
        elif line.startswith('c3N'):
            c3N = line.split(':')[1] 
        elif line.startswith('c3G'):
            c3G = line.split(':')[1]
        elif line.startswith('c3B'):
            c3B = line.split(':')[1]
        elif line.startswith('c4N'):
            c4N = line.split(':')[1] 
        elif line.startswith('c4G'):
            c4G = line.split(':')[1]
        elif line.startswith('c4B'):
            c4B = line.split(':')[1]

【问题讨论】:

    标签: python file-io for-loop if-statement


    【解决方案1】:

    你应该想想这两行是如何相互作用的:

    elif line.startswith('c'):
    ...
    elif line.startswith('cP'):
    

    另外,你应该考虑使用字典来保存你的所有值,你可以大大缩短你的程序。

    【讨论】:

      【解决方案2】:

      那是一段非常可怕的代码。你真的需要所有这些元素都是单独的变量吗?为什么不写一本这样的字典:

      {'fN':'john',
       'fP':'1',
         ...
      }
      

      只需几行即可生成:

      dct = {}
      f = file(location, 'r')
      for line in f:
          k, v = line.split(':')
          dct[k] = v
      

      【讨论】:

      • 如果值包含另一个冒号,line.split(":", 1) 可能更可取。
      【解决方案3】:

      由于您将elif 用于除第一个之外的所有备选方案,因此最多只能评估一个备选方案。对于以cP 开头的行,条件

      elif line.startswith('c'):
      

      也将成立,因此不会考虑任何其他替代方案。

      也就是说,您最好将结果存储在字典中,可能是这样:

      d = dict(line.split(":", 1) for line in open(location))
      

      【讨论】:

        【解决方案4】:

        它不起作用,因为以cP 开头的行也以c 开头,并且您将c 条件放在cP 之前。


        您应该更好地重构代码以避免长 if/elif 链。这是非常难以维护的。我会使用字典和

         results = {}
         for line in file:
            (key, value) = line.split(':', 1)
            results[key] = value
        
         # use results['fN'] for your fN variable
        

        甚至更短:

         results = dict(line.split(':', 1) for line in file)
        

        (如果你必须使用 fN 作为一个独立的局部变量,你可以使用

         locals().update(line.split(':', 1) for line in file)
        

        但我不推荐。)

        【讨论】:

        • Idk 如果您使用过 Tkinter,但我试图将所有这些变量放入不同的输入框中,我认为我不能用字典来做到这一点。或者更可能我不知道如何
        • @Brandon:为什么不能在 Tkinter 中使用字典?
        • 愚蠢的问题dict[key]返回一个字符串
        【解决方案5】:

        由于名称 fN , fP , fE , mN, mP, .... 显然是已知且稳定的,并且由于函数定义中的 self 背叛了您想要创建的属性一个在文件中读取值的实例,并且由于文件具有 CSV 格式,我的建议是:

        import csv
        
        class A:
        def __init__(self):
            self.fN  = self.fP  = self.fE  = None 
            self.mN  = self.mP  = self.mE  = None
            self.a   = self.c   = self.s   = None
            self.zC  = self.hP  = self.cP  = None
            self.eN  = self.c1N = self.c1G = None
            self.c1B = self.c2N = self.c2G = None
            self.c2B = self.c3N = self.c3G = None
            self.c3B = None
        
        inst1 = A()
        
        with open('roro.txt','rb') as f:
            rid = csv.reader(f,delimiter=':')
            for row in rid:
                inst1.__dict__[row[0]] = row[1]
        
        
        print inst1.fP
        print inst1.s
        print inst1.c3B
        

        请注意,使用内置函数的名称(即 file)命名对象是一种不好的做法,并且不推荐使用 xreadlines() .

        另外,你定义global fileDirectory的意图是什么?

        语句global x 指定如果对象的创建是由于在下一行中对名称 x 的赋值完成的,则名称为 x 的对象必须被视为在全局级别的模块中。在您的代码中,没有对 fileDirectory 的赋值,这样会更好,因为将 fileDirectory 声明为全局可能会引发意想不到的错误。

        请注意,全局级别是更高级别,而不是函数的外部级别。检查以下代码:

        class A:
        
            def __init__(self):
                self.m = 0.00315879
        
            N = 101
        
            def f(self,x,y):
                print 'in f : x==',x,"  y+10==",y
                def g(a,b):
                    print 'in g : a==',a,'  b==',b
                    global m
                    global N
                    m = a*b
                    N = 5000010000
                    print 'in g : m = a*b ==',m
                    print 'in g : N==',N
        
        
                g(x+300,y+700)
                print 'in f, outside g: m==',m
                print 'in f, outside g: N==',N
        
        
        
        u = A()
        
        
        u.f(0,40)
        print
        print 'm at the global level==',m
        print 'N at the global level==',N
        print 'the instance attribute u.m==',u.m
        print 'the class attribute u.N==',u.N
        

        结果

        in f : x== 0   y+10== 40
        in g : a== 300   b== 740
        in g : m = a*b == 222000
        in g : N== 5000010000
        in f, outside g: m== 222000
        in f, outside g: N== 5000010000
        
        m at the global level== 222000
        N at the global level== 5000010000
        the instance attribute u.m== 0.00315879
        the class attribute u.N== 101
        

        【讨论】:

        • 只响应全局变量问题。这是因为程序的许多不同部分都需要文件目录,所以我将其设为全局变量
        • @Brandon 好的,但是名称为 fileDirectory 的对象是在什么级别创建的?我们没有在你的函数 fillWindow() 中看到这个创建,因为它是编写的。据我了解 global 语句 如果下一行中没有创建赋值语句 global 是没用的
        • idk 关卡的名称是什么,但它是最高的,就在导入的旁边
        • @Brandon 如果名称为 fileDirectory 的对象是在最高级别创建的(您的意思是名称为 _main_的模块> ,不是吗?),那么较低级别的声明global fileDirectory 是绝对没用的。您应该研究 Python 管理变量的方式(在文档中“变量”表示“名称”),在 (docs.python.org/reference/…) 中:“当在代码块中使用名称时,它使用最近的封闭来解析范围。对代码块可见的所有此类范围的集合称为代码块的环境。”
        • @Brandon 表示如果一个函数 h() 定义在一个函数 g() 中定义在一个函数 f() 在模块 M 中定义,在 h()的主体中的语句中涉及名称(又名“变量”)X > 触发解释器在函数 h() 的命名空间中搜索 X 和 X 指向的对象之间的绑定,如果在此命名空间中找不到 X,则 Python 在封闭范围内搜索也就是说在函数g();的命名空间中
        猜你喜欢
        • 1970-01-01
        • 2021-12-31
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多