Инкапсуляция - одна из основ ООП. Мы договариваемся использовать только часть функциональности класса, а взамен получаем возможность работать с самыми разными типами, даже с теми, которые будут написаны после окончания работы над текущим кодом.
Компилируемые языки реализуют инкапсуляцию методом принуждения. Программист отмечает методы и поля как личные или защищенные, а компилятор играет в большого брата и проверяет что все используется в корректном контексте. На моей памяти война за способ использования private/protected минимум пару раз принимала нешуточный оборот.
Попадая в питон С++/Java-программисты начинают искать замену родным private/protected в этом мире безудержного эксгибиционизма. И, как правило, быстро находят два подчеркивания. Не совсем то, что хотелось бы, но довольно сильно похоже на private. В итоге нижнее подчеркивание быстро становится самым популярным символом в коде.
Я попробую показать, что:
- '__' - не эквивалент private и решает совсем другие задачи;
- Можно отлично жить без private/protected/friend. Оружие массового запрещения не единственный способ реализовать инкапсуляцию;
- При желании можно написать аналог private/protected и даже более гибкий контроль доступа для python (в следующем посте)
Итак зачем в python поля с двумя подчеркиваниями в начале имени. Пусть у нас есть такой код:
Без подсветки синтаксисаfrom some_module import SomeClass
class SomeClassChildren(SomeClass):
def __init__(self):
super(SomeClassChildren, self).__init__()
self.some_field = 12
Допустим код SomeClass очень большой или нам не доступен или постоянно неконтролируемо меняется или по любой другой причине мы не может быть уверенны, что какое бы благозвучное имя не было выбрано для some_field мы не можем быть уверенны, что не затрем поле с таким же именем в родительском классе. Компилируемый язык решил бы эту проблему, не позволив нам создать поле, если поле с таким именем уже унаследовано. Это не решает проблему полностью, но избавляет нас от странного поведения.
Для этого в питоне и есть поля с двумя подчеркиваниями в начале (но без двух подчеркиваний в конце). Когда компилятор питона видит подобное имя он дописывает к нему в начало еще одно подчеркивание и имя текущего компилируемого класса. Это можно увидеть с помощью питоновского дизассемблера:
Без подсветки синтаксисаimport dis
class A(object):
def func(self, x):
self.__attr1
class B(A):
def func(self, x):
self.__attr2
class C(A):
def func(self, x):
class C1(object):
def func(self):
x.__attr3
dis.dis(C1.func)
def r(self):
self.__attr4
class D(object):
func = r
dis.dis(A.func)
dis.dis(B.func)
C().func(A())
dis.dis(D.func)
dis.dis(lambda: A.__attr5)
# dis.dis(A.func) 0 LOAD_FAST 0 (self) << object 3 LOAD_ATTR 0 (_A__attr1) << attribute name # == self._A__attr1 # dis.dis(B.func) 0 LOAD_FAST 0 (self) 3 LOAD_ATTR 0 (_B__attr2) # dis.dis(C1.func) 0 LOAD_DEREF 0 (x) 3 LOAD_ATTR 0 (_C1__attr3) # dis.dis(D.func) 0 LOAD_FAST 0 (self) 3 LOAD_ATTR 0 (__attr4) # dis.dis(lambda: A.__attr5) 0 LOAD_GLOBAL 0 (A) 3 LOAD_ATTR 1 (__attr5)
Итого '__' приводит к переименованию поля и позволяет использовать поля с одинаковыми именами в разных классах одной иерархии. Но это не мешает добраться до такого поля, например x._X__some_priv_field. BTW - если нужно сделать действительно скрытое поле, то можно и так:
Без подсветки синтаксисаclass MyProxy(object):
def __init__(self, proxifyed):
self.__dict__[self] = proxifyed # <<<
def __getattr__(self, name):
return getattr(self.__dict__[self], name)
self.__dict__ - обычный словарь и ключами в нем могут быть не только строки. Злоупотреблять таким хаком не стоит поскольку много различных библиотек, например сериализаторы, сильно удивятся увидев в __dict__ нестроковой ключ.
Итак: '__' - это очень специфический аналог частного поля и он предназначен для несколько других целей.
Модификаторы доступа защищают программиста от случайного и преднамеренного доступа к тем частям API, которые разработчик класса захотел скрыть.
Начнем со случайного доступа на примере С++. Случайно в нем можно вызвать:
- конструктор (присваиванием, в контейнере при копировании, etc)
- деструктор (по выходу объекта или его владельца из области видимости)
- оператор преобразования типа
- опечатавшись, скопировав неправильно код, etc
Последний пункт скорее из области фантастики. Все остальные тоже не применимы к питону. Питон не копирует объекты, все всегда передается и хранится по ссылке, deepcopy/loads не вызывают конструктор. Деструктор вызывается непонятно когда и чаще всего его вызов сложно контролировать. Доступ к имеющиеся преобразования типов бессмысленно запрещать (__str__, __int__). Так что операции, выполняемые питоном без явного указания программиста не особо нуждаются в разграничении доступа.
Кроме того в С++ в указанных случаях мы получим ошибку на этапе компиляции, а в случае с питоном - в этапе исполнения, когда уже будет не очень понятно что с нею делать.
Перейдем к преднамеренному вызову защищенного метода. Если очень хочется, то никакой private/protected не остановит:
#define protected public #include "foo.h" #undef protected
Есть еще 666 способов добраться до защищенного метода. Есть они и в Java (reflections) и в C#, иначе контейнеры внедрения зависимостей не смогли бы работать.
Итого - бессмысленно защищаться и от преднамеренного вызова. Всегда есть способ обойти такую защиту. Да и если кто-то очень хочет - пусть вызывает. А для защиты от случайного вызова обычно достаточно просто не упоминать метод/поле в документации.
Документация - первая линия инкапсуляции в python.
В С++ чтение заголовочных файлов - достаточно распространенный способ получения документации и модификаторы доступа в данном случае тоже помогают. В python чтение исходников затруднено тем, что код и прототип смешаны. При желании для донесения информации до читающих исходники случая можно помечать функции декоратором, подобным этому:
Без подсветки синтаксисаdef protected(func):
return func
class X(object):
@protected
def some_method(self):
pass
Наконец очень распространенный способ посмотреть что можно сделать с объектом это интроспекция. Например, если нажать <tab> после x. в ipython, то он покажет какие поля и методы есть у объекта x. Для управлением видимостью методов/полей в случае такой интроспекции в питоне есть метод __dir__:
Без подсветки синтаксисаclass X(object):
def __dir__(self):
return 'public_method public_field'.split()
def __init__(self):
self.public_field = 12
self.protected_field = 13
def public_method(self):
pass
def protected_method(self):
pass
dir(X()) # == ['public_method', 'public_field']
Интроспеция - вторая линия инкапсуляции в python.
Пользуйтесь этими способами и не засоряйте питон подчеркиваниями. В следующем посте мы объединим автоматизируем dir и сделаем для питона аналог private.
Ссылки:koder-ua.blogspot.com/2013/11/python.html
Исходники этого и других постов со скриптами лежат тут - github.com/koder-ua. При использовании их, пожалуйста, ссылайтесь на koder-ua.blogspot.com.
26 comments:
Когда изучаю какой-нибудь API на предмет "какую можно использовать функцию, чтобы сделать то, чего я хочу" конечно же обходим стороной подчёркнутые методы - сразу понятно, что автор кода не рассчитывал, что ты это захочешь вызвать.
Обычно API изучают подокументации, куда такие методы просто не попадают
А какие в итоге задачи в Python решает двойное подчеркивание?
Интроспеция, наверное речь идет об Интроспекции.
Или это новый термин?
Молоді батьки оригінально подякували одне одному за народження доньки, як це було читайте тут.
Thanks for sharing such a informative post with us...
Digital Marketing Courses in Bangalore
Actually I read it yesterday but I had some thoughts about it and today I wanted to read it again because it is very well written.
ai course in nashik
Great post i must say and thanks for the information. Education is definitely a sticky subject. However, is still among the leading topics of our time. I appreciate your post and look forward to more.
ai course in nashik
I have to search sites with relevant information on given topic and provide them to teacher our opinion and the article.
data science training in mangalore
Excellent Blog! I would like to thank for the efforts you have made in writing this post. I am hoping the same best work from you in the future as well. I wanted to thank you for this websites! Thanks for sharing. Great websites!
data science training in delhi
Awesome blog. I enjoyed reading your articles. This is truly a great read for me. I have bookmarked it and I am looking forward to reading new articles. Keep up the good work!
data science course in kochi
I am sure that this is going to help a lot of individuals. Keep up the good work. It is highly convincing and I enjoyed going through the entire blog.
data science course in indore
Nice blog, very interesting, for further knowledge you can also look into
Business Analytics Course in Pune
Provides the best Business analytic course in Pune along with future placements.
https://360digitmg.com/india/business-analytics-training-in-pune
Amazing article! So informative and elaborate...
I came across fantastic course in Data science - do check it out
https://360digitmg.com/india/data-science-using-python-and-r-programming-pune
I came across fantastic course in Data Science Course in Punedo check it out
Amazing article! So informative and elaborate...
Nice Article, a Great experience for me to reading this info. thanks for sharing the information with us. keep updating your ideas.
Looking for the best PPC course in Bangalore India? Learn PPC from Ranjan Jena, 10+ Years Expert Google Ads Trainer. 1000+ Students Trained @ eMarket Education, Koramangala, Bangalore.
Best Online Digital Marketing Courses in Bangalore, India
Best Digital Marketing Institute in Bangalore
I must appreciate you for providing such valuable content for us. To make our dreams a reality, everyone has to put up a hard struggle in their life. Here I am making my small effort to arrange up the list of highest paying Jobs in India. We provide one of the best courses for you.
1) Data Science course in Delhi
2) Artificial Intelligence Course in Delhi
3) Machine Learning course in Delhi
4) Business Analytics courses in Delhi
5) Digital marketing course in Delhi
6) Full Stack Software Developer course in Delhi.
amf og
atomik moon rocks
ambrosia strain
blue dream vs og kush
citrix leafly
citrix strain
eleven roses strain
gorilla gas strain
pootie tang strain
pootie tang strain
laughing gym look alikes
Virtualmindinfotech is one of the leading Top Digital Marketing Agencies in Noida sector 3, India. We provide a 360° approach to digital marketing with services ranging from search to content to social media to website design to mobile advertising. Hire us for creative website design in Noida, website development in Greater Noida & Mobile App Design & Development services in India.
One Up Psilocybin mushroom chocolate Bars for sale
Glo Carts
Raw Garden Carts
Free e liquids
Juul pods near me
Cheap vape juice
E cigs near me
How much are puff bars
Buy clenbuterol steroids online
Buy steroids online
Buy clenbuterol steroids online
kitten shelter homes
american shorthair cat-for sale
pure Crack Cocaine Online 98%
Cocaine Online Vendor, Best Cocaine Online Vendor, Fishscale cocaine online shop, where to buy Fishscale cocaine, blow drug, Bolivian Cocaine Canada, Bolivian Cocaine for sale, Bolivian Cocaine Online, Buy Peruvian Pink Cocaine, cocaina no flour, cocaine for sale, How can I buy Peruvian Cocaine, How to buy Peruvian Cocaine, Order peruvian cocaine, order pure cocaine online, Peruvian Cocaine buy, Peruvian Cocaine buy online, Peruvian cocaine for sale, Peruvian flake, peruvian pink cocaine, pink cocaine, Pink Cocaine for sale online, pink peruvian coke, powder cocaine, Powder Cocaine for sale online, Purchase Powder Cocaine Online, Pure Bolivian Cocaine Online, strawberry cocaine, Where can I buy Peruvian Cocaine, Where to buy Peruvian Cocaine, Where to Buy Peruvian Pink Cocaine online, Where to buy real Peruvian Pink Cocaine Online
Wholesale Cocaine Online Vendor
Wholesale Bolivian Cocaine Online Vendor
Wholesale Uncut Cocaine Online Vendor
Wholesale Colombian Cocaine Online Vendor
Wholesale Black, Brown & china Heroin Online Vendor
Wholesale Kilocaine Powder Online Vendor
Wholesale Peruvian Cocaine Online Vendor
Wholesale Volkswagen Cocaine Online Vendor
whatsApp number : +15024936152
wickr:movecokee
Hippiestore.org
Post a Comment