Простой интерактивный сценарий резервного копирования


Как я могу улучшить это?

На GitHub

import os, platform, logging, logging.handlers, glob
from time import *
import tarfile
import zipfile, zlib

class backup:
    source_s = ''
    destination_d = ''

    def __init__(self):

        if strftime("%p") == 'AM':
            if strftime("%I") in ['12', '01', '02', '03', '04', '05', '06', '07', '08', '09', '10', '11']:
                time_d = 'Morning'
            else:
                pass 
        if strftime("%p") == 'PM':
            if strftime("%I") in ['12', '01', '02', '03']:
                time_d = 'Afternoon'
            elif strftime("%I") in ['04', '05', '06', '07', '08']:
                time_d = 'Evening'
            elif strftime("%I") in ['09', '10', '11']:
                time_d = 'Night'
            else:
                pass 

        print "Date:",strftime("%d %b %Y")
        print "Hi There, Today is ",strftime("%A")," And time is ", strftime("%I:%M:%S:%P"),  ", So on this beautiful ",strftime("%A"),"", time_d," I welcome you to this Backup program."


    def source_destination(self):
        w_s = True
        w_ss = True
        while w_s:
            source = raw_input('Please Enter The Complete Path of Source Directory: ')
            if source == '':
                print "***You have not Specified Anything***"
                print "***Source Directory is required in Order to make backup***"
                continue
            elif os.path.exists(source) == False:
                print "***Source Path Does not Exists***"
                print "***Please check source path and Try Again***"
                continue
            else:
                print "***Specified source path is ACCEPTED***"
                w_s = False
                backup.source_s = source



        while w_ss:
            destination = raw_input('Please Enter Complete Path of Destination Directory:')
            destination = destination.replace(' ','_')

            if destination == '':
                print "***You have not Specified Anything***"
                print "***Destination Directory is required to store the backup files***"

                continue
            elif os.path.exists(destination) == False:
                print "***Destination Path Does not Exists***"
                decision = raw_input('Do you Want me to Create Destination For you (yes or no or just hit enter for yes):')
                if decision == 'yes':
                    print "***Destination Path Will now be created***"
                    os.mkdir(destination)
                    print "***Directory has been created now***"
                    print "***Program will now continue***"
                    backup.destination_d = destination
                    w_ss = False
                elif decision == 'no':
                    print "***As You Wish, because Your wish is my Command***"
                    print "***Program will now Terminate***"
                    print "Bye !!!"
                    exit()
                elif decision == '':
                    print "***Destination Path Will now be created***"
                    mk_d = 'mkdir {0}'.format(destination)
                    os.system(mk_d)
                    print "***Directory has been created now***"
                    print "***Program will now continue***"
                    backup.destination_d = destination
                    w_ss = False
                elif decision not in ['yes','no','']:
                    print "***What you think you are doing, you just have to choose yes or no, is it that HARD?***"
                    print "***Try again now***"
                    continue
            elif os.path.exists(destination) == True:
                if os.path.isdir(destination)== False:
                    print "***Specified location is a file and not a directory, so try again and enter path of a directory***"
                    continue
                else:
                    print "***Specified destination path is ACCEPTED***"
                    w_ss = False
                    backup.destination_d = destination

            else:
                print "***Specified destination path is ACCEPTED***"
                w_ss = False
                backup.destination_d = destination

    def compress(self):
        source = backup.source_s
        destination = backup.destination_d

        w_sss = True
        f_name = raw_input('Please Enter The Desired name for output file(without extension):')

        if f_name == '':
            print "***You have not specified any name so DEFAULT will be used.(i.e 'untitled')***"
            f_name = 'untitled'
        else:
            pass

        while w_sss:
            c_method = raw_input('How you want your backup file to be compressed ?(tar, tar.gz, tar.bz2, or zip):') 

            if c_method == 'tar':
                ff_name = f_name.replace(' ', '_') + '.tar'
                w_sss = False
            elif c_method == 'tar.gz':
                ff_name = f_name.replace(' ', '_') + '.tar.gz'
                w_sss = False
            elif c_method == 'tar.bz2':
                ff_name = f_name.replace(' ', '_') + '.tar.bz2'
                w_sss = False
            elif c_method == 'zip':
                ff_name = f_name.replace(' ', '_') + '.zip'

                w_sss = False

            elif c_method == '':
                print "***You have not selected any method of compression***"
                print "***Please select atleast one method of compression***"

                continue
            else:
                print "***Sorry, The method you specified is not supported yet***"
                print "Please choose from the given options i.e tar, tar.gz, tar.bz2 or zip "

                continue

        suffix = ("/")
        if source.endswith(suffix) == True:
            pass 
        else:
            source = source + os.sep
        if destination.endswith(suffix) == True:
            pass 
        else:
            destination = destination + os.sep

        values = [source, destination, ff_name]

        if c_method == 'tar':
            print "***Compression can take sometime depending upon method you selected and the size of the source, so please be patient***"
            tar = tarfile.open(destination+ff_name, 'w')
            for item in os.listdir(source):
                print "Adding",item,"to archive"
                tar.add(os.path.join(source,item))


            tar.close()
            print "Operation successful"
            exit()
        elif c_method == 'tar.gz':
            print "***Compression can take sometime depending upon method you selected and the size of the source, so please be patient***"
            tar = tarfile.open(destination+ff_name, 'w:gz')
            for item in os.listdir(source):
                print "Adding",item,"to archive"
                tar.add(os.path.join(source,item))


            tar.close()
            print "Operation successful"
            exit()
        elif c_method == 'tar.bz2':
            print "***Compression can take sometime depending upon method you selected and the size of the source, so please be patient***"
            tar = tarfile.open(destination+ff_name, 'w:bz2')
            for item in os.listdir(source):
                print "Adding",item,"to archive"
                tar.add(os.path.join(source,item))

            tar.close()
            print "Operation successful"
            exit()
        else:
            print "***Compression can take sometime depending upon method you selected and the size of the source, so please be patient***"
            zipf = zipfile.ZipFile(destination+ff_name,"w", compression=zipfile.ZIP_DEFLATED)
            def recursive_zip(a, b):
                for item in os.listdir(b):
                    if os.path.isfile(os.path.join(b, item)):
                        print "Adding",item,"to archive"
                        a.write(os.path.join(b, item))
                    elif os.path.isdir(os.path.join(b, item)):
                        recursive_zip(a, os.path.join(b, item))



            recursive_zip(zipf, source)
            zipf.close()
            print "Operation successful"
            exit()




try:
    p = backup()
    p.source_destination()
    p.compress()
except KeyboardInterrupt:
    print "Why are you leaving me "
    reason = raw_input("1. Your program is not good enough 2. I will be back (1 or 2):")
    if(reason == '1'):
        print "Thanks for using my program, I will try to Improve it, so till then, Good Bye !"
        exit();
    elif(reason == '2'):
        print "OK then, See you Soon"
        exit()
    else:
        print "Invalid Input !!!"
        exit()

except EOFError:
    print "Why are you leaving me "
    reason = raw_input("1. Your program is not good enough 2. I will be back (1 or 2):")
    if(reason == '1'):
        print "Thanks for using my program, I will try to Improve it, so till then, Good Bye !"
        exit();
    elif(reason == '2'):
        print "OK then, See you Soon"
        exit()
    else:
        print "Invalid Input !!!"
        exit()


3090
2
задан 11 ноября 2011 в 06:11 Источник Поделиться
Комментарии
1 ответ

import os, platform, logging, logging.handlers, glob
from time import *
import tarfile
import zipfile, zlib

class backup:

Руководство по стилю Python рекомендует верблюжьего для имен классов

    source_s = ''
destination_d = ''

Почему эти атрибуты класса, а не атрибутами экземпляра?

    def __init__(self):

if strftime("%p") == 'AM':
if strftime("%I") in ['12', '01', '02', '03', '04', '05', '06', '07', '08', '09', '10', '11']:
time_d = 'Morning'

Я рекомендую не использовать _d в переменной имя, не понятно, что значит. Название переменных с чем-то значимым.

            else:
pass
if strftime("%p") == 'PM':
if strftime("%I") in ['12', '01', '02', '03']:
time_d = 'Afternoon'
elif strftime("%I") in ['04', '05', '06', '07', '08']:
time_d = 'Evening'
elif strftime("%I") in ['09', '10', '11']:
time_d = 'Night'
else:
pass

Не преобразовать время в строку, а затем проверить его, это будет легче, если вы получаете время как числа

current_time = time.localtime()
if 0 <= current_time.tm_hour < 12:
time_d = 'Morning'

Для автономного блока такого размера, я бы переместить его в отдельной функции, которая возвращает time_d

        print "Date:",strftime("%d %b %Y")
print "Hi There, Today is ",strftime("%A")," And time is ", strftime("%I:%M:%S:%P"), ", So on this beautiful ",strftime("%A"),"", time_d," I welcome you to this Backup program."

def source_destination(self):
w_s = True
w_ss = True

Плохие имена переменных, они довольно неисповедимы

        while w_s:
source = raw_input('Please Enter The Complete Path of Source Directory: ')
if source == '':
print "***You have not Specified Anything***"
print "***Source Directory is required in Order to make backup***"
continue

Это продолжать бессмысленно, потому что остальная часть кода-это еще заблокировать, избавиться от этого.

            elif os.path.exists(source) == False:
print "***Source Path Does not Exists***"
print "***Please check source path and Try Again***"
continue

Здесь же

            else:
print "***Specified source path is ACCEPTED***"
w_s = False

Используйте перерыв, кто-то, возможно, говорил вам не использовать перерыв, они ошибались. Перерыв может быть плохо для читабельности, но булевых флагов хуже.

                backup.source_s = source

Не начинай данные на ваш класс, сохраните ее на себя.

        while w_ss:

Вы устанавливаете w_ss выше, не делайте этого. набор переменных близко к их использованию

            destination = raw_input('Please Enter Complete Path of Destination Directory:')
destination = destination.replace(' ','_')

Магически замена деталей пути привлекли мое внимание

            if destination == '':
print "***You have not Specified Anything***"
print "***Destination Directory is required to store the backup files***"

continue
elif os.path.exists(destination) == False:
print "***Destination Path Does not Exists***"
decision = raw_input('Do you Want me to Create Destination For you (yes or no or just hit enter for yes):')
if decision == 'yes':

используйте, если решение == 'да' или решение == ": чтобы избежать дублирования

                    print "***Destination Path Will now be created***"
os.mkdir(destination)
print "***Directory has been created now***"
print "***Program will now continue***"

Ваш сценарий слишком принты. Он говорит много еще чего он делает.

                    backup.destination_d = destination
w_ss = False

как и прежде, булевы флаги задерживаются Гото. Не используйте их, если необходимо. Используйте перерыв.

                elif decision == 'no':
print "***As You Wish, because Your wish is my Command***"
print "***Program will now Terminate***"
print "Bye !!!"
exit()

Делают это, как правило, не считается хорошим тоном. Нет ничего ужасно неправильно с ним, но, как правило, вы должны прекратить вашу программу, вернувшись обратно в основной цикл.

                elif decision == '':
print "***Destination Path Will now be created***"
mk_d = 'mkdir {0}'.format(destination)
os.system(mk_d)

Почему вы используете систему для того чтобы сделать каталог? Использование операционной системы.функция mkdir, как вы сделали выше

                    print "***Directory has been created now***"
print "***Program will now continue***"
backup.destination_d = destination
w_ss = False
elif decision not in ['yes','no','']:
print "***What you think you are doing, you just have to choose yes or no, is it that HARD?***"
print "***Try again now***"
continue

Не оскорбляй пользователей

            elif os.path.exists(destination) == True:

Не использовать == правда просто использовать , если ОС.путь.существует(назначения):
если ОС.путь.isdir(пункт назначения)== ложь:

То же самое с ложное. использовать если не ОС.путь.isdir(пункт назначения)

                    print "***Specified location is a file and not a directory, so try again and enter path of a directory***"
continue
else:
print "***Specified destination path is ACCEPTED***"
w_ss = False
backup.destination_d = destination

else:

Это может случиться? Вы либо окажетесь в пункте назначения существует или назначения не существует категории

                print "***Specified destination path is ACCEPTED***"
w_ss = False
backup.destination_d = destination

Эта функция слишком долго. Вы должны разбить его. Я хочу сделать эту функцию что-то вроде:

   def backup_destination(self):
while True:
destination = raw_input()
if validate_destination(destination):
self.destination = destination
return

Посмотрим, как она коротка и как легко это, чтобы увидеть, что делает его. Все детали спрятаны в других функциях.

    def compress(self):
source = backup.source_s
destination = backup.destination_d

w_sss = True

Вы понимаете, что вы можете повторно использовать то же имя переменной для разных функций, не так ли?

        f_name = raw_input('Please Enter The Desired name for output file(without extension):')

if f_name == '':
print "***You have not specified any name so DEFAULT will be used.(i.e 'untitled')***"
f_name = 'untitled'
else:
pass

Нет необходимости в собственной пустой else пункт

        while w_sss:
c_method = raw_input('How you want your backup file to be compressed ?(tar, tar.gz, tar.bz2, or zip):')

if c_method == 'tar':
ff_name = f_name.replace(' ', '_') + '.tar'
w_sss = False
elif c_method == 'tar.gz':
ff_name = f_name.replace(' ', '_') + '.tar.gz'
w_sss = False
elif c_method == 'tar.bz2':
ff_name = f_name.replace(' ', '_') + '.tar.bz2'
w_sss = False
elif c_method == 'zip':
ff_name = f_name.replace(' ', '_') + '.zip'

w_sss = False

вместо того, чтобы использовать

    if c_method in ('tar','tar.gz','tar.bz2','zip'):
ff_name = f_name.replace(' ','_') + '.' + c_method
break

Это уменьшает дублирование

            elif c_method == '':
print "***You have not selected any method of compression***"
print "***Please select atleast one method of compression***"

continue
else:
print "***Sorry, The method you specified is not supported yet***"
print "Please choose from the given options i.e tar, tar.gz, tar.bz2 or zip "

continue

suffix = ("/")

В скобки ничего не делать

        if source.endswith(suffix) == True:
pass
else:
source = source + os.sep

Почему вы используете "/" выше и ОС.здесь сентября? Использование операционной системы.сентября везде

        if destination.endswith(suffix) == True:
pass

Пока нет пустым, если блоки, инвертировать логику, если заявление
другое:
назначение = назначение + ОС.сентября

Вы делаете то же самое для назначения и источника, написать функцию, чтобы сделать это

        values = [source, destination, ff_name]

Неиспользуемых переменных, удалить его

        if c_method == 'tar':
print "***Compression can take sometime depending upon method you selected and the size of the source, so please be patient***"

У вас же печати в каждом если заблокировать, скопировать его вне блока if

            tar = tarfile.open(destination+ff_name, 'w')

использование операционной системы.путь.присоединяйтесь, чтобы объединить куски пути. Он будет заботиться о ОС.сентября вы имели дело раньше

            for item in os.listdir(source):
print "Adding",item,"to archive"
tar.add(os.path.join(source,item))

tar.close()
print "Operation successful"
exit()

опять же, выход midscript считается плохим тоном. (в большинстве случаев)

        elif c_method == 'tar.gz':
print "***Compression can take sometime depending upon method you selected and the size of the source, so please be patient***"
tar = tarfile.open(destination+ff_name, 'w:gz')
for item in os.listdir(source):
print "Adding",item,"to archive"
tar.add(os.path.join(source,item))

tar.close()
print "Operation successful"
exit()

Посмотрим, как это точно так же, как в первом случае, но с другой режим, написать функцию, которая принимает в качестве параметра режим

        elif c_method == 'tar.bz2':
print "***Compression can take sometime depending upon method you selected and the size of the source, so please be patient***"
tar = tarfile.open(destination+ff_name, 'w:bz2')
for item in os.listdir(source):
print "Adding",item,"to archive"
tar.add(os.path.join(source,item))

tar.close()
print "Operation successful"
exit()

И снова!

        else:
print "***Compression can take sometime depending upon method you selected and the size of the source, so please be patient***"
zipf = zipfile.ZipFile(destination+ff_name,"w", compression=zipfile.ZIP_DEFLATED)
def recursive_zip(a, b):
for item in os.listdir(b):
if os.path.isfile(os.path.join(b, item)):
print "Adding",item,"to archive"
a.write(os.path.join(b, item))
elif os.path.isdir(os.path.join(b, item)):
recursive_zip(a, os.path.join(b, item))

recursive_zip(zipf, source)

Почему вы поддерживаете рекурсивный для молнии, но больше никто?

            zipf.close()
print "Operation successful"
exit()

Молнии отличается, но похож на другие. Я думал, что они разделяют код, но это АБ это сложнее.

try:
p = backup()

Не используйте одну букву имена переменных, если аббревиатура является очень распространенным

    p.source_destination()
p.compress()
except KeyboardInterrupt:
print "Why are you leaving me "
reason = raw_input("1. Your program is not good enough 2. I will be back (1 or 2):")
if(reason == '1'):
print "Thanks for using my program, I will try to Improve it, so till then, Good Bye !"
exit();
elif(reason == '2'):
print "OK then, See you Soon"
exit()
else:
print "Invalid Input !!!"
exit()

except EOFError:
print "Why are you leaving me "
reason = raw_input("1. Your program is not good enough 2. I will be back (1 or 2):")
if(reason == '1'):
print "Thanks for using my program, I will try to Improve it, so till then, Good Bye !"
exit();
elif(reason == '2'):
print "OK then, See you Soon"
exit()
else:
print "Invalid Input !!!"
exit()

используйте кроме (KeyboardInterrupt, eoferror генерируется): чтобы поймать несколько исключений

Вообще


  1. У вас есть много бесполезных и впредь заявления, которые ничего не делают

  2. Вы используете переменные типа boolean флаг, вы должны использовать перерыв

  3. Ваши имена переменных зашифрованы

  4. Вы дублируете много логики. Вы должны стремиться иметь каждый кусок логики раз

  5. Ваши функции имеют тенденцию быть длинными и сложными, они должны быть разбиты на более мелкие функции

  6. Ваше сравнение логических значений == правда и == ложь нет!

6
ответ дан 11 ноября 2011 в 02:11 Источник Поделиться