2010-07-28 79 views
2

这里是代码!python:正确使用全局变量

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仅通过2的功能可以看出,我应该让全球?如果不是那么我应该怎么称呼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 

回答

5

作为一个经验法则,避免全局变量。

这里,很容易: 让get_file返回数据 那么你可以说

data = get_file() 
samples_subset1(data) 

另外,我会做对文件的顶部全部进口

+0

非常感谢你 – 2010-07-28 15:08:41

+2

为了不听起来像“做这样做!” - 想象你想要导入几个文件。或者将几个数据集应用于处理函数。然后,你想能够告诉函数它应该工作的是什么 - 这将会随着全局变量方法变得丑陋。我不认为我曾经在我的代码中找到需要全局变量的东西,这不是基于我个人的懒惰;) – Nicolas78 2010-07-28 15:09:56

+1

哦,并使start_file为get_file的参数,而你在它:) – Nicolas78 2010-07-28 15:10:57

3

如果你必须使用全局(有时我们必须),你可以用Pythonic的方式来定义它,并且只允许某些模块访问它,而不必在所有函数/类的顶部添加关键字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 
+0

true。该文件应该叫cfg.py然后 – Nicolas78 2010-07-28 15:20:25

+0

好抓nicolas78!更新。 – dls 2010-07-28 15:22:16

2

如果要在两个或多个函数之间共享数据,那么通常最好使用一个类并将函数转换为方法,并将全局变量转换为类实例上的属性。

顺便说一句,你不需要每个函数结尾的return语句。如果您想要返回值或在函数中间返回,则只需显式返回。

+0

非常感谢。这很有帮助。你可以请演示给我看我如何使用这个代码的类? – 2010-07-28 15:35:05