Есть несколько вещей, которые мы можем сделать, чтобы очистить код. Мы закончим тем, что избавимся от глобальной переменной к концу.
Вместо того, чтобы ждать до конца получения содержимого каталога, мы можем получить его в самом начале. Таким образом, позже мы можем обрабатывать строки текста и содержимое каталога точно так же.
import os
import operator
query_list = ["look", "for", "these"]
search_object = "name_of_file_or_directory"
if os.path.isfile(search_object):
with open(search_object, "r") as file:
lines = file.read().split("\n")
elif os.path.isdir(search_object):
lines = os.listdir(search_object)
# At this point, lines is just a list of text - we don't care where it came from.
search_mode = input("Are you looking for objects that (1) exactly match or (2) contain the query? ")
matched = []
def comparison():
if search_mode == "1" and operator.eq(string, query) or search_mode == "2" and operator.contains(string, query):
matched.append(string)
return matched
for query in query_list:
def search_loop(container):
# container is either list of filenames or list of lines
global string
for string in container:
matched = comparison()
return matched
# We were able to remove checks from here
matched = search_loop(lines)
print(matched)
Раньше мы проверяли каждый раз, какой тип операции выполнять (точное совпадение или содержит). Вместо этого мы можем выбрать опцию прямо, когда получим пользовательский ввод и назначить его одному имени для последующего использования.
import os
import operator
query_list = ["look", "for", "these"]
search_object = "name_of_file_or_directory"
if os.path.isfile(search_object):
with open(search_object, "r") as file:
lines = file.read().split("\n")
elif os.path.isdir(search_object):
lines = os.listdir(search_object)
search_mode = input("Are you looking for objects that (1) exactly match or (2) contain the query? ")
# Because the interface of both functions is the same we can use them directly.
# If they were not the same then we could write an adapter function that would make them have
# the same signatures so they could be used in the same way below.
if search_mode == "1":
search_op = operator.eq
elif search_mode == "2":
search_op = operator.contains
matched = []
for query in query_list:
for string in lines:
if search_op(string, query):
matched.append(string)
print(matched)
Теперь, когда у нас есть более четкое представление о частях программы, мы можем разбить его на функции. Использование функций дает частям программы конкретные имена, а также помогает сузить область действия переменных, которые они используют. Чем меньше переменных используется в любом фрагменте кода, тем легче это будет понять позже. Мы избегаем глобальных переменных, тщательно выбирая наши функции - одним из важных критериев, который мы могли бы использовать, является то, что все в функции является автономным и не должно ссылаться на что-либо извне.
Мы также будем использовать соглашение if __name__ == '__main__'
, чтобы при желании мы могли включить наш скрипт из другого скрипта.
import os
import operator
def get_contents(search_object):
if os.path.isfile(search_object):
with open(search_object, "r") as file:
return file.read().split("\n")
elif os.path.isdir(search_object):
return os.listdir(search_object)
def get_search_function(user_input):
if search_mode == "1":
return operator.eq
elif search_mode == "2":
return operator.contains
def find_matches(match_function, query_list, lines):
matched = []
for query in query_list:
for string in lines:
if match_function(string, query):
matched.append(string)
return matched
if __name__ == "__main__":
search_object = "name_of_file_or_directory"
lines = get_contents(search_object)
search_mode_input = input("Are you looking for objects that (1) exactly match or (2) contain the query? ")
search_function = get_search_function(search_mode_input)
query_list = ["look", "for", "these"]
matches = find_matches(search_function, query_list, lines)
print(matches)
raise
соответствующую ошибку (для чего-то, что можно обработать) или assert
(для чего-то, что мы не ожидайте, что это произойдет, и не сможет оправиться от этого). argparse
, могут упростить принятие аргументов в скрипт, поэтому нам не нужно жестко кодировать значения переменных. sys.stdin
и предоставить его пользователю для генерации текста и передачи его в программу. например: cat words.txt | python script.py
для содержимого или ls . | python script.py
для файлов в каталоге. Я не пользовался этой библиотекой S/MIME, но мое приложение пользуется другой библиотекой от того же поставщика, и это хорошо работает:
http://www.chilkatsoft.com/mime-dotnet.asp
Их библиотека, чтобы сделать p7s подписи являются отдельными, который мог бы быть проблемой в зависимости от Вашего бюджета:
Довольно трудно реализовать полный s/mime, поскольку требуется большая дополнительная работа. Можно использовать компоненты SMIME в SecureBlackbox для задачи.
Обновление: SecureBlackbox является нашим продуктом. Это полностью поддерживает Silverlight и Windows Phone (включая Манго).
Взгляните на Rebex Secure Mail . Это очень стабильная библиотека, которую я использую уже много лет. Это 100% управляемый код, и исходный код также доступен.
В CodeProject доступен довольно хороший класс S / MIME.
http://www.codeproject.com/KB/security/CPI_NET_SecureMail.aspx