Архив рубрики: Без рубрики

приватные атрибуты в python

Ну нет приватных членов в питоне, ну нет…
Не надо писать С++/Java подобный код:

class C(object):
    def __init__(self):
        self.__name = 'default'

    def set_name(self, name):

        self.__name = name

    def get_name(self):

        return self.__name

Пробуем
>>>С().__name

Traceback (most recent call last):
  …
    C().__name

AttributeError: C instance has no attribute '__name'

Посмотрим на список атрибутов объекта

>>>С().__dict__
{'_C__name': 'default'}

Ну и в догонку меняем атрибут

>>>С()._C__name = 'new_name'

Двойное подчеркивание всего лишь соглашение, интерпретатор ничего не прячет,

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

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


Ссылки

https://docs.python.org/2/library/stdtypes.html#object.__dict__
http://stackoverflow.com/questions/70528/why-are-pythons-private-methods-not-actually-private

Автор: Евгений Курочкин

Браслет из лент мастер класс

Весенний браслет из ленты и бусин

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

Браслет из лент мастер класс

Браслет из лент мастер класс

Читать

Делаем мультизагрузочную флешку программой MultiSystem


Вот и настал тот момент, когда мне надоело таскать с собой кучу разных дисков и флешек. Стал искать решение этой проблемы в интернете. После недолгих поисков остановился на программке MultiSystem LiveUSB. Она позволяет запихнуть на одну флешку много разных образов в iso. И действительно, зачем устанавливать к примеру на 2-х гиговую флешку один образ размером, ну скажем, 800 мегабайт? Получается, что оставшееся свободное место у нас просто пропадает. Плюс всегда под рукой необходимый софт не только для установки его, но и для диагностики железа.

Установить сию программу на комп можно следующим образом. Открываем наш любимый терминал и вводим следующие команды:


sudo apt-add-repository 'deb http://liveusb.info/multisystem/depot all main'

wget -q http://liveusb.info/multisystem/depot/multisystem.asc -O- | sudo apt-key add —

sudo apt-get update && sudo apt-get install multisystem -y 

Готово. Программа поставилась. Находим ее в Меню->Стандартные.

Теперь поговорим о ее использовании. Для начала немного о флеш-накопителях. Емкость может быть любой, а вот отформатирована она должна быть в FAT32 и никак иначе. Отформатировать ее в Linux Mint 16 Cinnamon можно встроенным средством, которое находится в Меню->Стандартные. А в любых других дистрибутивах Linux Mint программой Gparted (если она не стоит у вас, то ставится с терминала командой sudo apt-get install gparted).
Итак, вставляем заранее отформатированную флешку в порт и запускаем MultiSystem. Видим следующее окно, в котором выбираем нашу флешку и нажимаем кнопку «ПОДТВЕРДИТЬ».
Затем нас спрашивают, уверены ли мы, что ставим Grub2 на нашу флешку:
Нажимаем ОК если уверены и видим следующее окно:
Перетаскиваем заранее подготовленные образы в маленькое окошечко внизу окна (не промахнетесть куда, ибо написано):

Затем вводим пароль администратора и ждем загрузки образа на флешку:

Так же поступаем с остальными образами, которые мы ходим добавить.
Также можно настроить внешний вид Grub2. Для этого переходим на вторую вкладку окна и нажимаем кнопку «Настройка Grub2».

В итоге видим такое окошко, в котором можно вставить свою картинку на фон (нажав на стандартную картинку откроете стандартное окно файлменеджера), заменить цвета текста, цвет фона экрана, цвета рамки и курсора на свои, отредактировать системные файлы Grub`а (если не знаете, что это такое — не нажимайте):
По окончанию настроек цветовой гаммы нажимаем «Закрыть» и после обновления Grub`а мы возвращаемся в предыдущее окно.
Чтобы записать образ Windows, необходимо перейти во вкладку «Non-free» и скачать/ установить все, что там находится. При загрузке компьютера с USB-носителя, пункты, относящиеся к Windows XP, будут находиться в подменю Grub4Dos, а пункты Windows 7— в подменю Syslinux.
Нажимаем кнопку «Выход» или просто закрываем окно.
Вот и все. Необходимую флешку мы с Вами создали. Для ее проверки просто перезагрузитесь с флешки, либо проверьте ее на виртуальной машине, если последняя стоит.

Автор: Роман Дмитриевич

Установка Google Chrome

Тема достаточно разжеванная на многих блогах и форумах. Тем не менее поговорим о ней. По умолчанию в репозитариях Linux Mint/Ubuntu в наличии имеется только Chromium. Но многие привыкли пользоваться именно Google Chrome. Потому у многих, особенно у новичков, возникает логичный вопрос: «А где бы скачать и как бы поставить Chrome?». Ответ очень прост.

Заходим на официальный сайт и нажимаем кнопку «Загрузить Chrome». По умолчанию загрузится последняя доступная версия браузера в формате инсталяционного пакета deb. Запускаем его либо через браузер, либо через менеджер файлов. Устанавливаться он будет через программу установки пакетов Gdebi. 
Находим его в Меню — Интернет. 

Радуемся жизни и свежему Google Chrome.

И не надо присоединять никаких там сторонних репозитариев.

Автор: Роман Дмитриевич

Подчеркнутая защищенность

Инкапсуляция — одна из основ ООП. Мы договариваемся использовать только часть функциональности класса, а взамен получаем возможность работать с самыми разными типами, даже с теми, которые будут написаны после окончания работы над текущим кодом.

Компилируемые языки реализуют инкапсуляцию методом принуждения. Программист отмечает методы и поля как личные или защищенные, а компилятор играет в большого брата и проверяет что все используется в корректном контексте. На моей памяти война за способ использования 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

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)

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)

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#, иначе контей