Автор оригинала: Gareth Dwyer.
Существует множество стандартных и сторонних библиотек Python, которые полезны, но редко используются начинающими и даже промежуточными пользователями Python. В этом посте освещаются некоторые из моих любимых библиотек и даются практические демонстрации некоторых функций. Я намерен, чтобы этот пост оставался “живым”, то есть я буду продолжать добавлять библиотеки и фрагменты кода по мере их обнаружения.
проверка (стандартная библиотека)
Я разрабатывал на Python в течение многих лет, прежде чем впервые использовал библиотеку inspect , но теперь я часто использую ее. Я нахожу полезным получить доступ к стеку и получить исходный код функций.
Базовый регистратор Python
Библиотека Python logging действительно хороша и полнофункциональна, и почти во всех случаях вы должны использовать ее (или другую библиотеку журналов). В качестве быстрой и грязной альтернативы давайте посмотрим, насколько легко зарегистрировать сообщение об ошибке вместе с датой и временем и именем функции, которая вызвала ошибку.
import inspect # gives us access to the stack
from datetime import datetime
LOG = True # set to False to suppress output
def log(message):
"""Log message with datetime and function name"""
if LOG:
n = datetime.utcnow()
f = inspect.stack()[1][3]
print("{} - {}: {}".format(n, f, message))
def problem_function():
"""Trigger Exception and log result"""
try:
lst = [1,2,3]
idx = 4
return lst[idx]
except IndexError:
log("Couldn't get element {} from {}".format(idx, lst))
def call_problem_function():
"""Call problem function"""
return problem_function()
def main():
call_problem_function()
if __name__ == "__main__":
main()
В приведенном выше надуманном примере у нас есть problem_function , которая должна регистрировать вывод о том, что пошло не так. Вместо того, чтобы просто печатать результат, мы определяем простую функцию log . Этот:
- Проверяет, нужен ли нам вывод (если
LOGglobal установлен вВерно) - Выводит пользовательское сообщение вместе с именем функции, вызвавшей его, и текущим временем
Мы можем получить доступ к стеку вызовов функций с помощью inspect.stack() Мы берем из него второй элемент ( inspect.stack()[1] ), так как первым всегда будет сама функция log , а еще дальше будет функция, которая вызвала log() . Мы получаем второй элемент ( inspect.stack()[1][3] ) так как это имя функции.
Так называемая “отладка printf” определенно не является лучшей практикой, и обычно есть лучшие способы, но большинство людей виновны в ее использовании, и это часто полезно. Иногда добавление некоторой информации из стека значительно облегчает понимание того, что именно не так с вашим кодом.
TextBlob (сторонняя библиотека)
Возможно, самая известная библиотека для обработки естественного языка (NLP) в Python в NLTK . Я не большой поклонник NLTK . Еще одна хорошая библиотека – Space , которая решает многие проблемы с NLTK . Однако пространство гораздо более современное и все еще лишено некоторой функциональности. Он также довольно ресурсоемкий и медленно инициализируется (что расстраивает прототипирование).
Еще одна хорошая библиотека для NLP-это Pattern , но она доступна только для Python 2. TextBlob построен поверх NLTK и Pattern (но он работает для Python 3). Я нахожу, что иногда это хороший компромисс между простотой и функциональностью. Он превращает строки языка в “большие двоичные объекты”, и вы можете легко выполнять с ними общие операции. Например:
from textblob import TextBlob
negative_sentence = "I hated today"
positive_sentence = "Had a wonderful time with my goose, my child, and my fish"
neutral_sentence = "Today was a day"
# sentiment analysis
neg_blob = TextBlob(negative_sentence)
pos_blob = TextBlob(positive_sentence)
neu_blob = TextBlob(neutral_sentence)
print(neg_blob.sentiment)
print(pos_blob.sentiment)
print(neu_blob.sentiment)
# output
# >>>Sentiment(polarity=-0.9, subjectivity=0.7)
# >>>Sentiment(polarity=1.0, subjectivity=1.0)
# >>>Sentiment(polarity=0.0, subjectivity=0.0)
# pluralization
print("{}->{}".format(pos_blob.words[6], pos_blob.words[6].pluralize()))
print("{}->{}".format(pos_blob.words[7], pos_blob.words[7].pluralize()))
print("{}->{}".format(pos_blob.words[8], pos_blob.words[8].pluralize()))
print("{}->{}".format(pos_blob.words[-1], pos_blob.words[-1].pluralize()))
# output
# >>>goose->geese
# >>>my->our
# >>>child->children
# >>>fish->fish
# Parts of Speech (POS) tagging
print(pos_blob.tags)
# ouput
# >>> [('Had', 'VBD'), ('a', 'DT'), ('wonderful', 'JJ'), ('time', 'NN'), ('with', 'IN') ('my', 'PRP$'), ('goose', 'NN'), ('my', 'PRP$'), ('child', 'NN'), ('and', 'CC'), ('my', 'PRP$'), ('fish', 'NN')]
nouns = ' '.join([tag[0] for tag in pos_blob.tags if tag[1] == "NN"])
print(nouns)
# ouput
#>>> 'time goose child fish'
Мы видим, что он может довольно хорошо идентифицировать позитивные и негативные настроения. В TextBlob анализ настроений состоит из двух частей: полярности (то есть того, насколько позитивным или негативным является настроение) и субъективности (то, насколько самоуверенным является предложение). Я нахожу оценку субъективности менее полезной и менее точной и обычно использую только полярность. Тональность-это просто именованный кортеж, поэтому вы можете получить доступ к полярности с помощью neg_blob.sentiment[0] , например.
Он также довольно хорошо справляется с множественным числом существительных и может изменить гусь на гуси и т. Д. Это не идеально (например, брюки становится брюки ), но это самое простое решение, которое я нашел для плюрализации, которое работает большую часть времени.
Чтобы получить теги POS, мы обращаемся к атрибуту tags , поэтому мы можем легко извлечь все существительные из предложения, например.
Вывод
На данный момент я добавил только пару библиотек и примеров, но этот пост будет продолжать расти. Если есть что-то, что, по вашему мнению, должно быть включено, не стесняйтесь комментировать ниже или чирикать @sixhobbits , и я подумаю о том, чтобы добавить это.