2

私は運動をしました、そしてそれは今良くて走っています。この演習の目的は、FTPサーバーからファイルをダウンロードしてzipし、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()

了解しました。命名規則はそれを私に任せています。しかし、すべてのグローバル変数を使用せずに再コーディングする方法の例を尋ねたいと思います。ご協力いただきありがとうございます!

4

4 に答える 4

4

メソッドには必ずパラメーターを指定する必要があります。

続行する方法は次のとおりです。

  1. メソッドが何をしているかを特定します。それぞれに正確な目標が 1 つだけある必要があります
  2. その目的に必要なものを特定し、それを引数リストに入れます
  3. 返すものを特定して返す
  4. メイン関数は問題なく、これらの変数を一元化するのに最適な場所です

グローバルを使用せず、1 つの関数/1 つのメソッドを持つことの最も良い点の 1 つは、何か問題が発生したときにテスト/デバッグが非常に簡単になることです。

例:

あなたのrequireと、それらをグローバルではなく引数にしdownload_files()ますdownloadstemp_path

于 2012-07-04T07:42:33.347 に答える
2

現在、あなたには 4 つのグローバルがありますmain。(temp_path, uploads, downloadsおよびftp)。

まず、global の行を削除 (コメント) すると、これら 4 つの変数が local から に変わりますmain。しかし、それでは他の機能からアクセスできなくなります。したがって、それらを関数に渡す必要があります。

そのために、これらの変数を必要とする関数にパラメータとして追加できます。したがって、たとえば、tryブロックは..に変更されます。

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

ここで、パラメータの追加に合わせて、関数も変更する必要があります。tryブロックから呼び出される関数のシグネチャは次のようになります。

def download_files(downloads, temp_path):

def zipping_files(temp_path):

def upload_files(ftp):

global filepath同様に、他の関数 (例: )にあるグローバルも削除できますzipping_files()

于 2012-07-04T08:08:10.937 に答える
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()

どんな提案もすべて考慮されます! 再度、感謝します!

于 2012-07-04T08:48:25.260 に答える
-1

Python は実際にはグローバル変数をサポートしていません。一般に、それらは悪い考えです。データを引数として渡すか、関数をクラスにラップして、パラメーターをクラス メンバーとして使用します。

(技術的には、python にはglobalキーワードがありますが、すべてのグローバル変数のすべての関数でそれを使用する必要があります。それはあるべき姿と同じくらい醜いです。使用しないでください。)

于 2012-07-04T07:45:35.513 に答える