python: 全局变量的正确使用

2 投票
3 回答
2427 浏览
提问于 2025-04-16 01:58

这是代码!

import csv

def do_work():
      global data
      global b
      get_file()
      samples_subset1()
      return

def get_file():

      start_file='thefile.csv'

      with open(start_file, 'rb') as f:
        data = list(csv.reader(f))
        import collections
        counter = collections.defaultdict(int)

      for row in data:
        counter[row[10]] += 1
      return

def samples_subset1():

      with open('/pythonwork/samples_subset1.csv', 'wb') as outfile:
          writer = csv.writer(outfile)
          sample_cutoff=5000
          b_counter=0
          global b
          b=[]
          for row in data:
              if counter[row[10]] >= sample_cutoff:
                 global b
                 b.append(row) 
                 writer.writerow(row)
                 #print b[b_counter]
                 b_counter+=1
      return

我刚开始学Python。我的代码运行方式是先调用do_work,然后do_work会调用其他函数。以下是我的问题:

  1. 如果我需要data只被两个函数看到,我应该把它设为全局变量吗?如果不应该,那我该怎么调用samples_subset1?是从get_file里调用,还是从do_work里调用?

  2. 代码可以运行,但你能指出它写得好或不好的地方吗?

  3. 我正在处理一个CSV文件,步骤有很多。我把这些步骤分成不同的函数,比如get_filesamples_subset1,还有更多我会添加的函数。我现在这样做,都是从do_work里调用每个函数,这样做可以吗?

这是根据下面某个回答修改后的新代码:

import csv
import collections

def do_work():
      global b
      (data,counter)=get_file('thefile.csv')
      samples_subset1(data, counter,'/pythonwork/samples_subset1.csv')
      return

def get_file(start_file):

        with open(start_file, 'rb') as f:
        global data
        data = list(csv.reader(f))
        counter = collections.defaultdict(int)

      for row in data:
        counter[row[10]] += 1
      return (data,counter)

def samples_subset1(data,counter,output_file):

      with open(output_file, 'wb') as outfile:
          writer = csv.writer(outfile)
          sample_cutoff=5000
          b_counter=0
          global b
          b=[]
          for row in data:
              if counter[row[10]] >= sample_cutoff:
                 global b
                 b.append(row) 
                 writer.writerow(row)
                 #print b[b_counter]
                 b_counter+=1
      return

3 个回答

2

如果你想在两个或多个函数之间共享数据,通常更好的做法是使用一个类,把这些函数变成类的方法,把全局变量变成类实例的属性。

顺便说一下,并不是每个函数最后都需要有返回语句。只有在你想要返回一个值,或者在函数中间提前返回时,才需要明确地写出返回。

3

如果你必须使用全局变量(有时候确实需要),你可以用一种更符合Python风格的方式来定义它,这样就不需要在所有的函数或类的开头都写上讨厌的global关键字了。

你可以创建一个新的模块,里面只放全局数据(比如说叫csvGlobals.py):

# create an instance of some data you want to share across modules
data=[]

然后,每个你想要访问这些数据的文件可以这样做:

import csvGlobals

csvGlobals.data = [1,2,3,4]
for i in csvGlobals.data:
    print i
5

一般来说,尽量避免使用全局变量。

这里很简单: 用 let 来获取文件,然后返回数据, 这样你就可以这样说:

data = get_file()
samples_subset1(data)

另外,我会把所有的导入放在文件的最上面。

撰写回答