Четвертая часть серии статей про аналоги в Python и JavaScript.
В этой части: аргументы функций, создание и работа с классами, наследование, геттеры-сеттеры и свойства класса.
Краткое содержание предыдущих частей:
- Часть первая: приведение к типу, тернарный оператор, доступ к свойству по имени свойства, словари, списки, строки, конкатенация строк.
- Часть вторая: JSON, регулярки, ошибки-исключения
- Часть третья: современные Python и JS: строковые шаблоны (f-строки), распаковка списков, лямбда-функции, итерации по спискам, генераторы, множества.
Аргументы функций
У Питона обширный инструментарий для работы с аргументами функций — есть значения по умолчанию, переменное число позиционных и именованных аргументов (*args и **kwargs).
Когда вы передаете значение в функцию, вы можете указать имя аргумента которому это значение будет передано. В JS тоже существует такая возможность.
Значения по умолчанию для аргументов функций могут быть определены в Питоне:
from pprint import pprint def report(post_id, reason='not-relevant'): pprint({'post_id': post_id, 'reason': reason}) report(42) report(post_id=24, reason='spam')
В JS аналогично:
function report(post_id, reason='not-relevant') { console.log({post_id: post_id, reason: reason}); } report(42); report(post_id=24, reason='spam');
Позиционные аргументы в Питоне могут быть обработаны используя оператор *:
from pprint import pprint def add_tags(post_id, *tags): pprint({'post_id': post_id, 'tags': tags}) add_tags(42, 'python', 'javascript', 'django')
В JS обработка позиционных аргументов происходит при помощи оператора ...:
function add_tags(post_id, ...tags) { console.log({post_id: post_id, tags: tags}); } add_tags(42, 'python', 'javascript', 'django');
Именованные аргументы часто применяются в Питоне когда необходимо передавать изменяемое число аргументов:
from pprint import pprint def create_post(**options): pprint(options) create_post( title='Hello, World!', content='This is our first post.', is_published=True, ) create_post( title='Hello again!', content='This is our second post.', )
Передача множества именованных аргументов в JS реализуется с помощью словаря (options в данном примере):
function create_post(options) { console.log(options); } create_post({ 'title': 'Hello, World!', 'content': 'This is our first post.', 'is_published': true }); create_post({ 'title': 'Hello again!', 'content': 'This is our second post.' });
Классы и наследование
Питон — объектно-ориентированный язык. JS начиная с ECMAScript 6 также позволяет писать объектно-ориентированный код без всяких уловок и синтаксических оборотов.
Питон. Создаем класс, конструктор и метод для текстового представления объекта:
class Post(object): def __init__(self, id, title): self.id = id self.title = title def __str__(self): return self.title post = Post(42, 'Hello, World!') isinstance(post, Post) == True print(post) # Hello, World!
Аналогичные действия на JS:
class Post { constructor (id, title) { this.id = id; this.title = title; } toString() { return this.title; } } post = new Post(42, 'Hello, World!'); post instanceof Post === true; console.log(post.toString()); // Hello, World!
Создадим два класса Article и Link в Питоне, которые будут наследоваться от класса Post. Можно заметить, что мы используем функциюsuper для доступа к методам базового класса Post:
class Article(Post): def __init__(self, id, title, content): super(Article, self).__init__(id, title) self.content = content class Link(Post): def __init__(self, id, title, url): super(Link, self).__init__(id, title) self.url = url def __str__(self): return '{} ({})'.format( super(Link, self).__str__(), self.url, ) article = Article(1, 'Hello, World!', 'This is my first article.') link = Link(2, 'DjangoTricks', 'https://djangotricks.blogspot.com') isinstance(article, Post) == True isinstance(link, Post) == True print(link) # DjangoTricks (https://djangotricks.blogspot.com)
То же самое в JS:
class Article extends Post { constructor (id, title, content) { super(id, title); this.content = content; } } class Link extends Post { constructor (id, title, url) { super(id, title); this.url = url; } toString() { return super.toString() + ' (' + this.url + ')'; } } article = new Article(1, 'Hello, World!', 'This is my first article.'); link = new Link(2, 'DjangoTricks', 'https://djangotricks.blogspot.com'); article instanceof Post === true; link instanceof Post === true; console.log(link.toString()); // DjangoTricks (https://djangotricks.blogspot.com)
Свойства класса: геттеры и сеттеры.
В объектно-ориентированном программировании у классов есть атрибуты, методы и свойства. Свойства — это смесь атрибутов и методов. Вы можете обращаться со свойствами как с атрибутами, но где-то внутри они вызывают специальные методы называемые геттерами и сеттерами (getters/setters) для специфической обработки данных.
В данном примере на Питоне показан базовый способ описания геттера и сеттера для свойства slug с помощью декораторов:
class Post(object): def __init__(self, id, title): self.id = id self.title = title self._slug = '' @property def slug(self): return self._slug @slug.setter def slug(self, value): self._slug = value post = Post(1, 'Hello, World!') post.slug = 'hello-world' print(post.slug)
В JS геттер и сеттер для свойства slug могут быть описаны как:
class Post { constructor (id, title) { this.id = id; this.title = title; this._slug = ''; } set slug(value) { this._slug = value; } get slug() { return this._slug; } } post = new Post(1, 'Hello, World!'); post.slug = 'hello-world'; console.log(post.slug);
Выводы
- В обоих языках можно описать дефолтные значения у аргументов функций.
- В обоих языках можно передавать в функцию произвольное число именованных или позиционных аргументов.
- Оба языка поддерживают объектно-ориетированную парадигму программирования.
Ну, и напоследок автор оригинального поста предлагает купить у него пдфку с цветными шпаргалками по питону и джаваскрипту за пятнадцать баксов.
Распечатать и повесить на стену или сделать бумажный самолетик — решать вам!
ссылка на оригинал статьи https://habr.com/post/419271/
Добавить комментарий