2012-07-04 2 views
2

나는 운동을했으며 지금은 잘되고 달리고있다. 이 실습의 골자는 FTP 서버에서 파일을 다운로드하고 FTP 서버의 업로드 폴더에 다시 업로드하는 것입니다. 이 코드는 내 코드입니다.오해의 소지가있는 전역 변수

import os 
import zipfile 
import ConfigParser 
import ftputil 
import shutil 
import tempfile 
import time 


def download_files(): 
    # Alvin: Think of a better variable name 
    file_list = ftp.listdir(downloads) 
    for filename in file_list: 
     # Alvin should be ftp.path.join 
     source = os.path.join(downloads, filename) 
     target = os.path.join(temp_path, filename) 
     ftp.download(source, target) 

def zipping_files(): 
    dirlist = os.listdir(temp_path) 
    global filepath 
    filepath = os.path.join(temp_path, 'part2b.zip') 
    # Alvin: find better name for zip_name 
    global zip_name 
    zip_name = zipfile.ZipFile(filepath, 'w') 
    # Alvin: try not to use built-in names as variable names 
    for list in dirlist: 
     # Alvin: file_path, absolute_path 
     get_file = os.path.join(temp_path, list) 
     zip_name.write(get_file, 'part2b\\' + list) 

def upload_files(): 
    ftp.upload(filepath, uploads + '/part2b.zip') 

def main(): 
    # Alvin: Do not use globals. 
    # Alvin: remove useless and above all misleading comments 

    global temp_path 
    temp_path = tempfile.mkdtemp() 


    config = ConfigParser.ConfigParser() 
    config.readfp(open('config.ini')) 
    server = config.get('main', 'Server') 
    username = config.get('main', 'Username') 
    password = config.get('main', 'Password') 

    global uploads 
    uploads = config.get('main', 'Upload folder') 

    global downloads 
    downloads = config.get('main', 'Download folder') 

    #connect to ftp 
    global ftp 
    # Alvin: open ftp connection when you only need it. 
    ftp = ftputil.FTPHost(server, username, password) 

    try: 
     download_files() 
     zipping_files() 
     upload_files() 

    finally: 
     ftp.close() 
     zip_name.close() 
     shutil.rmtree(temp_path, 'true') 

    print "Successfully transferred files." 
    print "" 
    print "This will close in 5 seconds. . . . ." 
    time.sleep(5) 

if __name__ == '__main__': 
    main() 

괜찮겠습니다. 이름 지정 규칙을 준수하십시오. 그러나 모든 글로벌 변수를 사용하지 않고 어떻게 다시 코딩 할 수 있는지에 대한 예제를 원합니다. 당신의 도움을 주셔서 감사합니다!

+0

이러한 변수를 인수로 전달하십시오. – georg

+0

나는 그 제안을 시도 할 것이다, 실제로 나는 내 마음 속에서 그것을 가지고있다. 그러나 변수를 먼저 선언 할 지 확신 할 수 없는가? 또는 그것이 내 main() 함수에서 선언되었다는 것은 괜찮은가요, 미안 해요 파이썬에서 새로운 것. 어쨌든 고마워! – neo

+0

파이썬에서는 값을 할당하기 전에 변수를 선언 할 필요가 없습니다. –

답변

4

매개 변수를 메소드에 정확하게 제공해야합니다. 여기

계속 진행 할 수있는 방법입니다 :

  1. 당신의 방법은 무엇을하고 있는지 확인하고, 각각은 하나의 정확한 목표
  2. 은 그 목적을 위해 필요한 것을 식별하고 인수 목록
  3. 에 넣어 있어야한다
  4. 가 반환된다 무엇을 확인하고 반환
  5. 귀하의 주요 기능은 괜찮습니다, 그 변수를 중앙 집중화 수있는 완벽한 장소입니다

전역 변수를 사용하지 않고 하나의 함수/한 가지 방법을 사용하는 것이 가장 좋은 점 중 하나는 잘못되었을 때 테스트/디버그하는 것이 매우 쉽다는 것입니다.

예 : - 그들은 일반적으로 좋은 생각입니다 download_files()downloadstemp_path 필요 당신의

는, 그 인수하지 전역

+0

'try :'/'finally :'가 분할되어 zip과 같은 항목이 닫히는 경우 열립니다. – glglgl

+0

음, 물론, zip_files()가 zip_name을 여는 것이므로 닫아야 할 것입니다. –

+0

좋아, 필자는 함수에서 인수를 사용하려고합니다. 임이 끝날 때마다 너희들을 알려줄거야. 모든 도움을 주셔서 감사합니다! – neo

-1

파이썬은 정말 글로벌 변수를 지원하지 않습니다합니다. 데이터를 인수로 전달하거나 클래스에서 함수를 랩핑하고 매개 변수를 클래스 멤버로 사용하십시오.

(기술적으로, 파이썬은 글로벌 키워드를 가지고 있지만, 당신은 모든 글로벌 변수에 대한 모든 기능에서 사용할 수 있습니다. 그것은 그것이 있어야처럼 추한 있습니다. 그것을 사용하지 마십시오.) 당신이

+0

이 답변은 잘못되었거나 나쁜 조언입니다. 글로벌 변수를 사용하기 위해서 키워드를 사용해야 만합니다. 그리고 네, 글로벌 (즉, 모듈) 변수를 갖는 것이 실제로 유용합니다. – PierreBdR

2

귀하의 main 현재 네 개의 전역이 있습니다. (temp_path, uploads, downloadsftp).

먼저 전역 변수가있는 행을 제거 (주석 처리)하면이 4 개의 변수가 로컬로 main이됩니다. 하지만 그렇게되면 다른 기능에 액세스 할 수 없게됩니다. 따라서 함수에 전달해야합니다.

이러한 목적으로 이러한 변수를 매개 변수로 추가 할 수 있습니다. 따라서 예를 들어, 당신은 try 블록으로 변경됩니다 ..

try: 
    download_files(downloads, temp_path) 
    zipping_files(temp_path) 
    upload_files(ftp) 

을 이제 매개 변수의 추가에 맞게, 너무 기능을 변경하여야한다. try 블록에서 호출되는 함수의 서명은 다음과 같습니다. (예 : zipping_files()에서 global filepath)

def download_files(downloads, temp_path): 

def zipping_files(temp_path): 

def upload_files(ftp): 

마찬가지로, 당신은 당신이 너무 다른 기능에있는 전역을 제거 할 수 있습니다.

0

귀하의 모든 도움에 감사드립니다 !! 귀하의 모든 대답은 매우 유용합니다! 이것은 내 마지막이며 실행 코드입니다.

import os 
import zipfile 
import ConfigParser 
import ftputil 
import shutil 
import tempfile 
import time 


def download_files(downloads, temp_path, server, username, password): 
    ftp = ftputil.FTPHost(server, username, password) 
    file_list = ftp.listdir(downloads) 
    for filename in file_list: 
     source = os.path.join(downloads, filename) 
     target = os.path.join(temp_path, filename) 
     ftp.download(source, target) 
    ftp.close() 

def zipping_files(temp_path): 
    file_list = os.listdir(temp_path) 
    filepath = os.path.join(temp_path, 'part2b.zip') 
    zip_file = zipfile.ZipFile(filepath, 'w') 
    for filename in file_list: 
     file_path = os.path.join(temp_path, filename) 
     zip_file.write(file_path, 'part2b\\' + filename) 
    zip_file.close() 

def upload_files(uploads, temp_path, server, username, password): 
    ftp = ftputil.FTPHost(server, username, password) 
    filepath = os.path.join(temp_path, 'part2b.zip') 
    ftp.upload(filepath, uploads + '/part2b.zip') 
    ftp.close() 

def main(): 

    temp_path = tempfile.mkdtemp() 

    config = ConfigParser.ConfigParser() 
    config.readfp(open('config.ini')) 
    server = config.get('main', 'Server') 
    username = config.get('main', 'Username') 
    password = config.get('main', 'Password') 
    uploads = config.get('main', 'Upload folder') 
    downloads = config.get('main', 'Download folder') 

    try: 
     download_files(downloads, temp_path, server, username, password) 
     zipping_files(temp_path) 
     upload_files(uploads, temp_path, server, username, password) 

    finally:  
     shutil.rmtree(temp_path, 'true') 

    print "Successfully transferred files." 
    print "" 
    print "This will close in 5 seconds. . . . ." 
    time.sleep(5) 

if __name__ == '__main__': 
    main() 

모든 제안 사항이 고려됩니다! 다시 한 번 감사드립니다!