Архив метки: Python

Разбор данных JSON в Python

JSON — это читаемый человеком текстовый формат данных. Он не зависит от языка и используется для обмена данными между приложениями.В этой статье мы объясним, как анализировать данные JSON в Python.

 

Python JSON

Модуль json позволяет кодировать и декодировать данные JSON является частью стандартной библиотеки Python.

JSON — это строка, представляющая данные. Кодирование или сериализация означает преобразование объекта Python в строку JSON, которую можно сохранить в файле или передать по сети. Декодирование или десериализация — обратный процесс кодирования, когда строка JSON преобразуется в объект Python.

Ниже приведена таблица, показывающая объекты Python и их эквивалентное представление JSON:











PythonJSON
dictobject
list, tuplearray
strstring
int, floatnumber
Truetrue
Falsefalse
Nonenull

 

Для работы с JSON просто импортируйте модуль вверху файла:

import json

 

Кодировка JSON в Python

Модуль json имеет два метода для кодирования объектов Python в JSON отформатированных строк: dump() и dumps().

Метод dump() отправляет вывод в файл-подобный объект. Он принимает два позиционных аргумента: объект, который должен быть закодирован, и объект в виде файла. Вот пример:

data = {

    "country": "Russia",

    "vehicle": {

        "name": "Volkswagen",

        "model": "T-Roc"

    }

}



with open("file.json", "w") as file:

    json.dump(data, file)

 

Если вы запустите скрипт, он создаст файл с именем file.json:

file.json

{"country": "Russia", "vehicle": {"name": "Volkswagen", "model": "T-Roc"}}

 

Метод dumps() работает так же, как и dump(), но вместо того, чтобы послать вывод в файл-подобный объект, он возвращает строку:

data = {

    "country": "Russia",

    "vehicle": {

        "name": "Volkswagen",

        "model": "T-Roc"

    }

}



json.dumps(data)

 

'{"country": "Russia", "vehicle": {"name": "Volkswagen", "model": "T-Roc"}}'

 

Оба метода принимают одинаковые ключевые аргументы. Например, если вы анализируете или отлаживаете данные JSON, вы можете указать уровень отступа:

data = {

    "country": "Russia",

    "vehicle": {

        "name": "Volkswagen",

        "model": "T-Roc"

    }

}



print(json.dumps(data, indent=2))

 

{

  "country": "Russia",

  "vehicle": {

    "name": "Volkswagen",

    "model": "T-Roc"

  }

}

 

Расшифровка JSON в Python

Для того, чтобы преобразовать JSON закодированные данные в объекты Python, использовать методы load() и loads().

Метод load() считывает структуру JSON из файла типа объекта и преобразует его в объект Python.

Допустим, у нас есть следующий файл JSON:

file.json

[

  {

    "userId": 1,

    "id": 1,

    "title": "Meet with Lisa",

    "completed": true

  },

  {

    "userId": 1,

    "id": 2,

    "title": "Design a prototype",

    "completed": false

  }

]

 

Чтобы преобразовать данные JSON в представление Python, вы должны использовать что-то вроде этого:

import json



with open('file.json') as f:

  data = json.load(f)



type(data)

 

JSON преобразуется в список Python, который вы можете использовать в своем коде:

<class 'list'>

 

Метод loads() преобразует строку, содержащую документ JSON на объект Python:

import json



json_str= '{"userId": "1", "id": "1", "title": "Meet with Lisa", "completed": "True"}'



print(json.loads(json_str))

 

Строка преобразуется в словарь Python:

{'userId': '1', 'id': '1', 'title': 'Meet with Lisa', 'completed': 'True'}

 

Вот более сложный пример, который показывает, как сделать запрос API и декодировать данные JSON:

import json

import requests



response = requests.get("https://jsonplaceholder.typicode.com/users")

users = json.loads(response.text)



print(users)

 

Вывод

Мы рассказали вам, как кодировать и декодировать данные JSON в Python.

Если у вас есть какие-либо вопросы или отзывы, не стесняйтесь оставлять комментарии.



2020-06-29T10:06:00
Python

Оператор Modulo в Python

Операция по модулю — это арифметическая операция, которая находит остаток от деления одного числа на другое. Остаток называется модулем операции.

Например, 5 деленное на 3, равно 1, с остатком 2, а 8, деленное на 4, равно 2, с остатком 0.

 

Оператор Modulo в Python

В Python оператор Modulo представлен знаком процента ( %). Синтаксис выглядит следующим образом:

num1 % num2

Вот пример:

5 % 4

1

 

Если делитель (второй аргумент) равен нулю, то возбуждается ошибка ZeroDivisionError:

5 % 0

ZeroDivisionError: integer division or modulo by zero

 

Оператор по модулю также принимает плавающие числа в качестве аргументов:

6.8 % 3.4

0.0

 

При форматировании строк символ % представляет оператор интерполяции.

 

Примеры

Одним из распространенных случаев использования оператора по модулю является проверка, является ли число нечетным или четным. Если число, деленное на 2, не имеет остатка, то это четное число. В противном случае, если он оставляет остаток от 1, то число нечетное:

num = 11



if (num % 2) == 0:

   print(num, "is even")

else:

   print(num, "is odd")

 

Если вы запустите приведенный выше код, 11 % 2 оставьте остаток 1 и код внутри оператора else будет выполнен:

11 is odd

 

Вот еще один пример, показывающий, как проверить, является ли число простым числом, используя оператор по модулю. Простое число — это положительное целое число, которое может быть разделено без остатка только на одно и на 1:

def isPrimeNumber(num):

  if num < 1:

    return False

  for i in range(2, num):

    if (num % i) == 0:

      return False

  else:

    return True

 

Сначала мы проверяем num, является ли число положительным числом. Затем мы проверяем, делится ли число на другое число в диапазоне от 2 или num без напоминания. Если ни одно из условий не выполнено, число простое.

Оператор по модулю также может быть использован для преобразования единиц измерения. В следующем примере показано, как преобразовать секунды в минуты:

def secondsToMinutes(sec):

  seconds = sec // 60

  minutes = sec % 60

  return "%d minutes and %d seconds" % (minutes, seconds)



secondsToMinutes(657)

'57 minutes and 10 seconds'

 

Оператор деления на две косые черты (//) округляет результат до ближайшего целого числа.

 

Вывод

В этой статье мы показали, как использовать оператор Python по модулю.

Если у вас есть какие-либо вопросы или отзывы, не стесняйтесь оставлять комментарии.



2020-06-19T13:48:26
Python 3

Как добавить элементы в список в Python (добавить, расширить и вставить)

При работе со списками в Python вам часто нужно добавлять новые элементы в список.

Тип данных списка Python имеет три метода для добавления элементов:

  • append() — добавляет один элемент в список.
  • extend() — добавляет элементы итерируемого в список.
  • insert() — вставляет один элемент в заданную позицию списка.

Все три метода изменяют список на месте и возвращают None.

 

Метод append() в списке Python

Метод append() добавляет один элемент в конец списка.

Синтаксис метода append() следующий:

list.append(element) 

Где, элемент element, который будет добавлен в список.

Вот пример:

characters = ['Tokyo', 'Lisbon', 'Moscow', 'Berlin'] 



characters.append('Nairobi')



print('Updated list:', characters)

Updated list: ['Tokyo', 'Lisbon', 'Moscow', 'Berlin', 'Nairobi']

 

Параметр element может быть объектом любого типа данных:

odd_numbers = [1, 3, 5, 7] 



even_numbers = [2, 4, 6]



odd_numbers.append(even_numbers)



print('Обновленный список:', odd_numbers)

Список even_numbers добавляется в список как один элемент odd_numbers.

Обновленный список: [1, 3, 5, 7, [2, 4, 6]]

 

Метод extend() в список Python

Метод extend() все элементы итератор к концу списка.

Синтаксис метода extend() следующий:

list.extend(iterable) 

 

Где iterable —  это итерация, добавляемая в список.

characters = ['Tokyo', 'Lisbon', 'Moscow', 'Berlin'] 



new_characters = ['Nairobi', 'Denver', 'Rio']



characters.extend(new_characters)



print('Список обновлен:', characters)

 

Список обновлен: ['Tokyo', 'Lisbon', 'Moscow', 'Berlin', 'Nairobi', 'Denver', 'Rio']

 

Аргументом может быть любой тип итерации:

animals = ['dog', 'cat']



# кортеж

mammals = ('tiger', 'elephant')



animals.extend(mammals)



print('Updated list:', animals)



# dictionary

birds = {'owl': 1, 'parrot': 2}



animals.extend(birds)



print('Updated list:', animals)

 

Updated list: ['dog', 'cat', 'tiger', 'elephant']

Updated list: ['dog', 'cat', 'tiger', 'elephant', 'owl', 'parrot']

 

Метод insert() в списке Python

Метод insert() добавляет один элемент в список по указанному индексу.

Синтаксис метода insert() следующий:

list.insert(index, element) 

 

Где index — это индекс элемента, перед которым нужно вставить, и elementэлемент, который нужно вставить в список. В Python индекс списка начинается с 0.

Вот пример:

fruits = ['raspberry', 'strawberry', 'blueberry'] 



fruits.insert(1, 'cranberry')



print('Updated list:', fruits)

Updated list: ['raspberry', 'cranberry', 'strawberry', 'blueberry']

 

Параметр element может быть объектом любого типа данных:

numbers = [10, 15, 20, 25] 



squares = [1, 4, 9]



numbers.insert(2, squares)



print('Updated list:', numbers)

 

Список squares вставляется как один элемент в список numbers.

Updated list: [10, 15, [1, 4, 9], 20, 25]

 

Вывод

Мы показали вам, как добавлять элементы в список в Python с использованием методов append(), extend() и insert(). Другой способ добавить элементы в список, использовать оператор +- для объединения нескольких списков.

Если у вас есть какие-либо вопросы или отзывы, не стесняйтесь оставлять комментарии.



2020-06-12T01:46:23
Python

Python. Давайте создадим простой HTTP-сервер

Веб-серверы есть везде.

Черт возьми, вы взаимодействуете с одним прямо сейчас!

Независимо от того, какой вы разработчик программного обеспечения, в какой-то момент вашей карьеры вам придется взаимодействовать с веб-серверами. Может быть, вы создаете сервер API для бэкэнда. Или, может быть, вы просто настраиваете веб-сервер для своего сайта.

В этой статье мы расскажем, как создать самый простой http веб-сервер на Python.

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

Если вы уже знаете, как работают веб-серверы, вы можете сразу перейти к этому разделу.

  • Что такое HTTP-сервер?
  • Адрес сокета TCP
  • Создайте простой файл HTTP
  • Создать HTTP веб-сервер

 

Что такое HTTP-сервер?

Веб-сервер HTTP — это не что иное, как процесс, который выполняется на вашем компьютере и выполняет ровно две вещи:

1- Прослушивает входящие HTTP-запросы на определенный адрес сокета TCP (IP-адрес и номер порта, о которых мы расскажем позже)

2- Обрабатывает этот запрос и отправляет ответ обратно пользователю.

 

Но что на самом деле происходит под капотом?

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

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

На высоком уровне, когда вы набираете www.yandex.ru  в своем браузере, ваш браузер создаст сетевое сообщение, называемое HTTP-запросом.

Этот запрос будет распространяться на компьютер yandex, на котором работает веб-сервер. Этот веб-сервер перехватит ваш запрос и обработает его, отвечая HTML-кодом домашней страницы yandex.

Наконец, ваш браузер отображает этот HTML на экране, и это то, что вы видите на своем экране.

Каждое взаимодействие с домашней страницей yandex после этого (например, когда вы нажимаете на ссылку) инициирует новый запрос и ответ точно так же, как первый.

Повторим еще раз: на машине, которая получает запрос http, работает программный процесс, называемый веб-сервером. Этот веб-сервер отвечает за перехват этих запросов и их обработку соответствующим образом.

Хорошо, теперь, когда вы знаете, что такое веб-сервер и какова его функция, вам может быть интересно, как запрос в первую очередь достигает машины yandex?

Хороший вопрос!

Позвольте нам объяснить, как, но опять же … на высоком уровне.

 

Адрес сокета TCP

Любое http-сообщение (будь то запрос или ответ) должно знать, как добраться до места назначения.

Чтобы достичь места назначения, каждое http-сообщение содержит адрес, называемый адресом TCP назначения.

И каждый TCP-адрес состоит из IP-адреса и номера порта.

Мы знаем, что все эти аббревиатуры (TCP, IP и т. д.) могут быть ошеломляющими, если ваши сетевые знания не сильны.

Так где же этот адрес, когда все, что вы сделали, и набрали www.yandex.ru в вашем браузере?

Ну, это доменное имя преобразуется в IP-адрес через большую распределенную базу данных, называемую DNS.

Хотите проверить, что это за IP-адрес?

Легко! Зайдите в свой терминал и сделайте следующее:

$ host yandex.ru

Yandex.ru has address 77.88.55.66                                                                                                                                               

Yandex.ru has address 5.255.255.70                                                                                                                                              

Yandex.ru has address 77.88.55.70                                                                                                                                               

Yandex.ru has address 5.255.255.60                                                                                                                                              

Yandex.ru has IPv6 address 2a02:6b8:a::a                                                                                                                                        

Yandex.ru mail is handled by 10 mx.Yandex.ru.

 

Как видите, как DNS переведет yandex.ru на любой из указанных выше адресов.

Один только IP-адрес позволит HTTP-сообщению поступить на нужный компьютер, но вам все равно нужен номер порта, чтобы HTTP-запрос поступил именно на веб-сервер.

Другими словами, веб-сервер — это обычное сетевое приложение, которое прослушивает определенный порт.

И HTTP-запрос ДОЛЖЕН быть адресован этому порту.

Так где же номер порта при вводе www.yandex.ru ?

По умолчанию номер порта равен 80 для http и 443 для https, поэтому даже если вы не указали номер порта явно, он все еще там.

И если веб-сервер прослушивает номер порта не по умолчанию (ни 80, ни 443), вы должны явно указать номер порта следующим образом:

www.yandex.ru:445

 

К настоящему времени у вас должна быть вся необходимая информация для создания http-сервера на Python.

Так что без дальнейших церемоний, давайте начнем.

 

Создайте простой файл HTML

Вот что мы хотим сделать.

Мы хотим создать простой http-сервер, который обслуживает статическую HTML-страницу.

Давайте создадим нашу HTML-страницу.

<html>

    <head>

        <title>Python-это потрясающе!</title>

    </head>

    <body>

        <h1>yandex</h1>

        <p>Поздравляю! Сервер HTTP работает!</p>

    </body>

</html>

 

Теперь сохраните этот файл как index.html.

Теперь, для обслуживания веб-страницы, следующим шагом является создание веб-сервера, который будет обслуживать эту HTML-страницу.

 

Создать HTTP веб-сервер

Чтобы создать веб-сервер в Python 3, вам нужно импортировать два модуля: http.server и socketserver

Обратите внимание, что в Python 2 был модуль с именем  SimpleHTTPServer. Этот модуль был объединен с http.server в Python 3

Давайте посмотрим на код для создания http-сервера

import http.server

import socketserver



PORT = 8080

Handler = http.server.SimpleHTTPRequestHandler



with socketserver.TCPServer(("", PORT), Handler) as httpd:

    print("serving at port", PORT)

    httpd.serve_forever()

 

Просто так у нас есть функциональный http-сервер.

Теперь давайте разберем этот код построчно.

Во-первых, как мы упоминали ранее, веб-сервер — это процесс, который прослушивает входящие запросы на определенный TCP-адрес.

И, как вы уже знаете, TCP-адрес идентифицируется по IP-адресу и номеру порта.

Во-вторых, веб-сервер также должен знать, как обрабатывать входящие запросы.

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

Конечно, эти обработчики могут делать все что угодно.

Но что вы думаете, какой самый основной обработчик?

Ну, это будет обработчик, который просто обслуживает статический файл.

Другими словами, когда мы заходим на yandex.ru, веб-сервер на другом конце отправляет обратно статический HTML-файл.

Это на самом деле то, что мы пытаемся сделать.

И это, и есть то, что является http.server.SimpleHTTPRequestHandler : простой обработчик HTTP-запросов, который обслуживает файлы из текущего каталога и любых его подкаталогов.

 

Класс socketserver.TCPServer

Теперь поговорим о классе socketserver.TCPServer.

Экземпляр TCPServer описывает сервер, который использует протокол TCP для отправки и получения сообщений (http — это протокол прикладного уровня поверх TCP).

Чтобы создать экземпляр TCP-сервера, нам нужны две вещи:

  1. TCP-адрес (IP-адрес и номер порта)
  2. Обработчик

 

socketserver.TCPServer(("", PORT), Handler)

 

Как видите, TCP-адрес передается в виде кортежа (IP-адрес, номер порта)

Передача пустой строки в качестве IP-адреса означает, что сервер будет прослушивать любой сетевой интерфейс (все доступные IP-адреса).

А поскольку PORT хранит значение 8080, сервер будет прослушивать входящие запросы на этот порт.

Для обработчика мы передаем простой обработчик, о котором мы говорили ранее.

Handler = http.server.SimpleHTTPRequestHandler

 

Ну, а как насчет serve_forever?

serve_forever — это метод в экземпляре TCPServer, который запускает сервер и начинает прослушивать и отвечать на входящие запросы.

Круто, давайте сохраним этот файл как server.py в том же каталоге, что и index.html, потому что по умолчанию SimpleHTTPRequestHandler будет искать файл с именем index.html в текущем каталоге.

В этом каталоге запустите веб-сервер:

$ python server.py

serving at port 8080

 

Благодаря этому теперь у вас есть HTTP-сервер, который прослушивает любой интерфейс на порте 8080 и ожидает входящие HTTP-запросы.

Пришло время для забавных вещей!

Откройте браузер и введите localhost:8080 в адресной строке.

Потрясающие! Похоже, все работает нормально.

Но что такое localhost ?

localhost — это имя хоста, которое означает этот компьютер. Он используется для доступа к сетевым службам, работающим на хосте, через петлевой сетевой интерфейс.

А поскольку веб-сервер прослушивает любой интерфейс, он также прослушивает интерфейс обратной связи.

Вы хотите знать, какой IP-адрес соответствует localhost?

Введите следующее:

$ host localhost

localhost has address 127.0.0.1

localhost has IPv6 address ::1

Host localhost not found: 3(NXDOMAIN)

 

Фактически вы можете полностью заменить localhost на 127.0.0.1 в вашем браузере, и вы все равно получите тот же результат.

 

Одно последнее слово

На самом деле вы можете запустить веб-сервер с python, даже не создавая никаких скриптов.

Просто зайдите в свой терминал и сделайте следующее (но убедитесь, что вы на Python 3)

python -m http.server 8080

 

По умолчанию этот сервер будет прослушивать все интерфейсы и порт 8080.

Если вы хотите прослушать определенный интерфейс, сделайте следующее:

python -m http.server 8080 --bind 127.0.0.1

 

Также начиная с Python 3.7, вы можете использовать флаг –directory для обслуживания файлов из каталога, который не обязательно является текущим каталогом.

Таким образом, теперь возникает вопрос: зачем вам когда-либо писать сценарий, когда вы можете просто вызывать сервер из терминала?

Хорошо, помните, что вы используете  SimpleHTTPRequestHandler. Если вы хотите создать свои собственные обработчики (что вы, вероятно, захотите), то вы не сможете сделать это из терминала.



2020-06-05T15:50:58
Python 3

Сортировка списка в Python

Сортировка данных — одна из самых распространенных задач при работе с Python. Например, вы можете отсортировать список членов команды по имени или список проектов в порядке приоритета.

В этой статье описывается, как сортировать списки в Python.

 

Sort() и sorted() в Python

В Python вы можете отсортировать список, используя встроенный метод list.sort() или встроенную функцию sorted().

Функция sorted() создает новый отсортированный список, в то время как метод list.sort() сортирует список на месте. Если вы хотите сохранить, несортированный список использовать функцию sorted(). Другое отличие состоит в том, что функция sorted() работает с любым повторяемым объектом.

Синтаксис sort()и sorted()следующий:

list.sort(key=function, reverse=Boolean)

 

sorted(iterable, key=function, reverse=Boolean)

 

Необязательные ключевые аргументы key и reverse имеют следующее значение:

  • key — Функция, которая принимает один аргумент и преобразует его перед сравнением. Функция должна возвращать одно значение, которое используется для сравнения сортировки.
  • reverse — Значение реверса может быть либо либо, True либо False. Значением по умолчанию является True. Когда для этого аргумента установлено значение false, список сортируется в обратном порядке.

Элементы списка сравниваются с помощью оператора < (меньше чем) и сортируются по возрастанию. Оператор < не поддерживает сравнения строки в целое число, так что если у вас есть список , содержащие строки и целые числа, то операция сортировки не удастся.

В следующем примере показано, как отсортировать список строк в алфавитном порядке:

directions = ["north", "east", "south", "west"] 



directions.sort()



print('Sorted list:', directions)

 

Sorted list: ['east', 'north', 'south', 'west']

 

Если вы хотите сохранить исходный список без изменений, используйте функцию sorted():

directions = ["north", "east", "south", "west"] 



sorted_directions = sorted(directions)



print('Sorted list:', sorted_directions)

 

Sorted list: ['east', 'north', 'south', 'west']

 

Чтобы отсортировать список в обратном (нисходящем) порядке, установите аргумент reverse в True:

directions = ["north", "east", "south", "west"] 



directions.sort(reverse=True)



print('Sorted list:', directions)

 

Sorted list: ['west', 'south', 'north', 'east']

 

Сортировка с функцией

Аргумент key принимает функцию и позволяет выполнять более сложные операции сортировки.

Самый простой пример — сортировка элементов по длине:

directions = ["Destroyer", "Alex", "AndreyEx", "Max"] 



directions.sort(key=len)



print('Sorted list:', directions)

 

Мы используем функцию len(), чтобы вернуть количество символов в строке, которая используется в качестве компаратора:

Sorted list: ['AndreyEx', 'Destroyer', 'Max', 'Alex']

 

Вы также можете создать пользовательскую функцию и использовать ее в качестве keyаргумента для сравнения. Вот пример, показывающий, как отсортировать список целых чисел по сумме их цифр:

def sum_digits(num): 

    digits = [int(x) for x in str(num)] 

    return sum(digits) 

      

numbers = [23, 77, 19, 310, 219] 



numbers.sort(reverse=True, key=sum_digits)



print('Sorted list:', numbers)

Sorted list: [77, 219, 19, 23, 310]

 

Другим примером может быть использование ключевого аргумента для сортировки сложного списка, такого как список кортежей:

numbers = [(3, 14), (1, 61), (2, 71)]



numbers.sort(key=lambda k: k[0])



print('Sorted list:', numbers)

 

Мы используем анонимную (лямбда) функцию, которая возвращает первый элемент кортежа. Список отсортирован по значению, возвращенному функцией:

Sorted list: [(1, 61), (2, 71), (3, 14)]

 

Тот же подход можно использовать для сортировки списка словарей:

elements = [

    {'name': 'Germanium', 'number': 25, 'symbol': 'ge'},

    {'name': 'Silver', 'number': 47, 'symbol': 'ag'},

    {'name': 'Iron', 'number': 26, 'symbol': 'fe'},

]



elements.sort(key=lambda k: k['name'])



print('Sorted list:', elements)

 

Лямбда-функция возвращает значение nameключа, которое используется для сравнения:

Sorted list: [

    {'name': 'Germanium', 'number': 25, 'symbol': 'ge'}, 

    {'name': 'Iron', 'number': 26, 'symbol': 'fe'}, 

    {'name': 'Silver', 'number': 47, 'symbol': 'ag'}

]

 

Лучший и более быстрый способ сортировки сложной функции — использовать функции модуля «Оператор». Вот пример:

from operator import itemgetter



elements = [

    {'name': 'Germanium', 'number': 25, 'symbol': 'ge'},

    {'name': 'Silver', 'number': 47, 'symbol': 'ag'},

    {'name': 'Iron', 'number': 26, 'symbol': 'fe'},

]



elements.sort(key=itemgetter('symbol')) 



print('Sorted list:', elements)

 

Функция itemgetter считывает значение ключа symbol:

Sorted list: [

    {'name': 'Silver', 'number': 47, 'symbol': 'ag'},

    {'name': 'Iron', 'number': 26, 'symbol': 'fe'},

    {'name': 'Germanium', 'number': 25, 'symbol': 'ge'}

]

 

Вывод

Мы показали вам, как сортировать списки в Python, используя метод sort() и функцию sorted().

Если у вас есть какие-либо вопросы или отзывы, не стесняйтесь оставлять комментарии.



2020-06-04T12:54:49
Python

Частные методы в Python

Понимание объектно-ориентированного программирования (ООП) имеет решающее значение, если вы хотите изучать Python.

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

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

Внимание: это будет длинные углубленная статья о частных методах, но если вы только хотите знать, как определять собственные методы в Python, вот tl;dr.

tl;dr — Префикс имени вашего атрибута или метода с одним подчеркиванием. Однако следует помнить, что Python не поддерживает инкапсуляцию, поэтому на самом деле ничего не является приватным.

 

Что такое частные методы?

Закрытый метод — это метод класса, который можно вызывать только изнутри класса, в котором он определен.

Это означает, что вы не можете (и не должны) получать доступ или вызывать эти методы извне класса.

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

Давайте рассмотрим простой пример частного метода на языке программирования, отличном от Python, скажем, Java. (Вы поймете, почему, позже)

class Hello {

  private void printHello() {

    System.out.println("Привет мир");

  }

}

 

В Java ключевое слово private используется для объявления частного метода. Итак, в этом примере мы определяем закрытый метод с именем printHello () в классе Hello.

Если вы попытаетесь вызвать этот метод извне класса, он просто не будет работать.

class Hello { 

  private void printHello() { 

    System.out.println("Привет мир");

  } 

}



public class HelloWorld{

  public static void main(String []args){

    Hello h = new Hello();

    h.printHello();

  }

}

 

Если вы выполните приведенный выше код, вы получите самоочевидное сообщение об ошибке компиляции.

$javac HelloWorld.java

error: printHello() has private access in Hello

  h.printHello();

   ^

1 error

 

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

class Hello {

  public void print() {

    printHello();

  }

  private void printHello() { 

    System.out.println("Привет мир");

  } 

}



public class HelloWorld{

  public static void main(String []args){

    Hello h = new Hello();

    h.print();

  }

}

 

Теперь, если вы запустите вышеупомянутую программу, вы не получите никаких ошибок, и вы получите строку «Привет мир», напечатанную на экране.

Обратите внимание, что частный метод printHello() лишь вызывается из внутрикласса и основной программы только называется публичным методом print().

Ну, это круто и все. Вы, наверное, уже знали это. Главный вопрос: зачем нам частные методы? и когда мы должны их использовать?

 

Когда вы должны использовать частные методы?

Прежде всего, помните, что инкапсуляция является одним из принципов объектно-ориентированного программирования (ООП).

Но что такое инкапсуляция на самом деле?

В объектно-ориентированном программировании инкапсуляция означает скрытие внутренней реализации объекта от внешнего мира.

Это означает, что единственный способ взаимодействия с объектом — через четко определенный интерфейс объекта.

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

Например, представьте объект, представляющий автомобиль, простой автомобиль, который позволяет вам только управлять им drive(), нажимая на педаль газа, или останавливать stop(), нажимая на тормоза.

В этом случае мы говорим, что drive() и stop() — это интерфейсы между вами (пользователем автомобиля) и экземпляром автомобиля.

Вам не нужно беспокоиться о том, как машина на самом деле движется или останавливается. Это не ваша проблема. Это то, что заботит конструктора автомобиля. Для вас все, что вы хотите сделать, это либо водить, либо останавливать машину.

Это круто и все, но давайте не будем сейчас говорить об автомобилях и говорить о программном обеспечении.

Давайте ответим на эти два вопроса.

Первое: мы упомянули, что инкапсуляция скрывает реализацию объекта от внешнего мира. Что такое внешний мир?

Внешний мир — это в основном другие разработчики, которые будут использовать проектируемый вами класс (это может быть вы).

Это НЕ конечный пользователь, который будет использовать ваш двоичный файл (у них будет либо пользовательский интерфейс, либо интерфейс командной строки), но инкапсуляция (по крайней мере, в мире ООП) касается потребителей разработчиков.

Второе: почему инкапсуляция полезна? Почему это имеет значение?

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

Представьте, что вы хотите заменить двигатель вашего автомобиля на новый, более мощный двигатель.

Нужно ли вам (пользователю автомобиля) узнавать что-то новое, чтобы иметь возможность управлять автомобилем после замены двигателя?

Точно нет. Тем не менее, все, что вам нужно сделать, это нажать на педаль газа, и машина будет двигаться.

Эта абстракция очень важна для написания поддерживаемого кода.

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

Это потому, что, пока интерфейс не меняется, все хорошо. Ничего не ломается.

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

В объектно-ориентированном программировании вы определяете этот интерфейс, объявляя открытые атрибуты и методы (public).

И вы достигнете инкапсуляции, объявив закрытые атрибуты и методы (private).

С этим введением, теперь мы можем начать статью.

 

Атрибуты и методы в Python: обновление

Прежде чем перейти к закрытым методам и атрибутам, давайте начнем с простого примера.

Давайте построим базовый класс.

class MyClass:

  def __init__(self):

    self.var = 1



  def get_var(self):

    return self.var

 

В этом примере мы определили класс с именем MyClass.

Внутри этого класса в методе __init__ мы определили один атрибут var, который инициализируется значением 1, и метод get_var, который возвращает значение var.

Теперь давайте прочитаем, а затем изменим значение var.

>> my_object = MyClass() # Создайте экземпляр MyClass

>> my_object.var   # Вызвать атрибут “var”

1                  # Результат - “1”, как и ожидалось

>> my_object.get_var()

1

>> my_object.var = 2

>> my_object.var

2

>> my_object.get_var()

2

 

Как видите, мы легко изменили значение var с 1 на 2.

Мы смогли это сделать, потому что у нас есть ДОСТУП к атрибуту var  извне.

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

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

 

Определение личных атрибутов и методов (private) в Python

Чтобы определить частные атрибуты или методы в Python, вот что вам нужно сделать.

Просто добавьте к имени префикс с единственным подчеркиванием.

Это так просто.

Теперь давайте перепишем приведенный выше пример, чтобы сделать var и get_var приватными.

class MyClass:

  def __init__(self):

    self._var = 1

  def _get_var(self):

    return self._var

 

Круто. Теперь давайте посмотрим, что происходит, когда мы gjпытаемся получить доступ к этому приватному атрибуту.

>> my_object = MyClass()  # Создание экземпляра MyClass

>> my_object._var  # Чтение _var

1

>> my_object._get_var()

1

 

Хм, подожди! Как?

Мы думали, что мы не можем получить доступ к приватным атрибутам или приватным методам! Как это возможно?

В Python закрытый доступ к закрытым атрибутам (и методам) не применяется.

Поэтому, когда мы говорим, что атрибуты, начинающиеся с одного подчеркивания, являются «частными», это просто соглашение. Но это не соблюдается.

Python не поддерживает инкапсуляцию. Мы любим инкапсуляцию, но разработчики языка решили не поддерживать ее. Ну что ж.

Утверждение о том, что инкапсуляция не является обязательной, не означает, что вам следует обращаться к атрибутам и методам с префиксом подчеркивания.

Не делайте этого, потому что это не обязательно.

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

Обычно эта статья должна заканчиваться здесь. Тем не менее, есть еще одна вещь, о которой мне нужно поговорить, прежде чем эта статья будет полностью завершена.

Мы говорили о том, что происходит, когда вы добавляете имена методов и атрибутов к одному подчеркиванию, но я уверен, что вы видели имена с двумя начальными подчеркиваниями (и без завершающих подчеркиваний).

Что делают эти двойные ведущие подчеркивания?

 

Префикс с двойным подчеркиванием (искажение имени)

Давайте вернемся к нашему классу и определим наши var и get_var (), но на этот раз используя двойные подчеркивания вместо одного.

class MyClass:

  def __init__(self):

    self.__var = 1



  def __get_var(self):

    return self.__var

 

Теперь давайте посмотрим, что происходит, когда мы пытаемся получить доступ к __var, как и раньше.

>> my_object = MyClass()

>> my_object.__var



AttributeError: 'MyClass' object has no attribute '__var'

 

Кажется, что Python не может найти атрибут __var , хотя мы только что определили его в нашем классе.

Точно так же, если вы попытаетесь получить доступ к __get_var (), вы получите ту же ошибку.

>> my_object.__get_var()



AttributeError: 'MyClass' object has no attribute '__get_var'

 

В чем дело?

Одна вещь, которую мы могли бы сделать, чтобы исследовать происходящее, это напечатать содержимое dir (my_object)

dir() перечисляет все атрибуты (и методы), которые имеет объект

>> dir(my_object)

['_MyClass__get_var', '_MyClass__var',...]

 

Интересно! Похоже, что Python переименовал переменные __var и __get_var в _MyClass__var и _MyClass__get_var соответственно.

Такое поведение при изменении имен атрибутов или методов называется искажением имен.

Манглинг имен затрудняет доступ к переменным извне класса, но он все еще доступен через _MyClass__var.

>> my_object._MyClass__var = 3

>> my_object._MyClass__var

3

 

Точно так же вы можете получить доступ к __get_var с его искаженным именем _MyClass__get_var.

Другими словами, вне класса вам нужно будет использовать искаженное имя атрибута, но внутри класса вы все равно можете получить доступ к атрибуту обычным способом. (посмотрите, как мы получили доступ к __var изнутри __get_var () )

Стоит отметить, что некоторые разработчики ошибочно используют искажение имен для обозначения частных методов и атрибутов.

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

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

Что вы должны сделать, это то, что вы должны следовать соглашению и использовать единственное подчеркивание, чтобы обозначить что-то как личное.

 

Вывод

В заключение, Python не поддерживает инкапсуляцию. Вам по-прежнему следует ставить перед вашими личными атрибутами и методами один знак подчеркивания,  чтобы пользователи вашего класса знали, что им не следует напрямую обращаться к этим атрибутам. С другой стороны, если вы являетесь пользователем класса, не обращайтесь к атрибутам или методам, которые начинаются с начального подчеркивания.



2020-05-29T20:56:14
Python