Быстрый в изучении - мощный в программировании
Скрипт ИНВЕСТОР на Python

Попробуйте себя в качестве инвестора имея в помощники мощный алгоритм советника на Python...

Все уроки по PyQt5

PyQt5 реализован как комплект Python-модулей. Он включает в себя около 620 классов и 6000 функций и методов...

Скрипт отправки SMS через Python

Была задача отправить SMS-ки большому списку номеров телефона с уточнением цены за всю рассылку "До" ее отправки...

ООП на Python

Подписаться на эту рубрику по RSS

Объектно-ориентированное программирование (ООП) - это способ организации программы позволяющий использовать один и тот же код многократно. В отличие от функции и модулей ООП позволяет не только разделить программу на фрагменты, но и описать предметы реального мира в виде объектов, а также организовать связи между этими объектами.
Доступ к атрибутам класса в языке Python

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

имя-экземпляра.имя-атрибута = значение
del имя-экземпляра.имя-атрибута

Альтернативным способом добавления, изменения либо удаления переменной экземпляра является использование встроенных функций Python:Далее...

Альтернативы статическим методам Python

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

При таком способе функции не требуется передавать экземпляр класса. Например, следующая версия spam.py действует одинаково в Python 3 и 2.7(правда, в этой версии инструкция print отображает лишние круглые скобки при выполнении под управлением Python 2.7):Далее...

Слоты и обобщенные инструмены в Python

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

Обобщенные инструменты, которые получают списки атрибутов или обращаются к атрибутам, используя имена в виде строк, например, должны использовать более универсальные механизмы, чем атрибут __dict__. К таким механизмам можно отнести встроенные функции getattr, setattr и dir, способные отыскивать атрибуты в обоих хранилищах, __dict__ и __slots__. В некоторых случаях для полноты картины может потребоваться проверить оба источника атрибутов.

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

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

Свойства класса Python

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

<Свойства> = property(<Чтение>[, <Запись>[, <Удаление>[, <Строка документирования>]]])

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

Далее...

Абстрактные методы в Python

Абстрактные методы содержат только определение метода без реализации. Предполагается, что класс-потомок должен переопределить метод и реализовать его функциональность. Чтобы такое предположение сделать более очевидным, часто внутри абстрактного метода возбуждают исключение.

Абстрактные методы

class Class1(object):
    def test(self, x):     # Абстрактный метод
        # Возбуждаем исключение с помощью raise
        raise NotImplementedError("Необходимо переопределить метод")
class Class2(Class1):      # Наследуем абстрактный метод
    def test(self, x):     # Переопределяем метод
        print x
class Class3(Class1):      # Класс не переопределяет метод
    pass
c2 = Class2()
c2.test(50)                # Выведет: 50
c3 = Class3()
try:                       # Перехватываем исключения
    c3.test(50)            # Ошибка. Метод test() не переопределен
except NotImplementedError, msg:
    print msg              # Выведет: Необходимо переопределить метод
Далее...

Статические методы

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

<Название класса>.<Название метода>(<Параметры>)
Кроме того, можно вызвать статический метод через экземпляр класса:

<Экземпляр класса>.<Название метода>(<Параметры>)
Пример использования статических методов вриведен ниже.

class Class1(object):
    @staticmethod
    def sum1(x, y):              # Статический метод
        return x + y
    def sum2(self, x, y):        # Обычный метод в классе
        return x + y
    def sum3(self, x, y):
        return Class1.sum1(x, y) # Вызов из метода класса
 
print Class1.sum1(10, 20)        # Вызываем статический метод
c1 = Class1()
print c1.sum2(15, 6)             # Вызываем метод класса
print c1.sum1(50, 12)            # Вызываем статический метод
                                 # через экземпляр класса
print c1.sum3(23, 5)             # Вызываем статический метод
                                 # внутри класса
Далее...

Классы нового стиля

Начиная с Python 2.2, помимо классических классов существует классы так называемого нового стиля. Классом нового стиля называется класс, у которого базовым классом является встроенный объект (например, list или dict) или объект object. Для классов старого и нового стили отличаются результатом выполнения функции type(), а также вывод атрибутов __class__ и __bases__ для экземпляров классов.

Классы нового стиля

class Class1:          # Классический класс
    pass
 
class Class2(object):  # Класс нового стиля
    pass
 
class Class3(list):    # Класс нового стиля
    pass
 
print type(Class1)     # Выведет: 
print type(Class2)     # Выведет: 
print type(Class3)     # Выведет: 
# __bases__ содержит кортеж с базовыми классами
 
print Class1.__bases__ # Выведет: ()
print Class2.__bases__ # Выведет: (,)
print Class3.__bases__ # Выведет: (,)
c1, c2, c3 = Class1(), Class2(), Class3()
 
print c1.__class__     # Выведет: __main__.Class1
print c2.__class__     # Выведет: 
print c3.__class__     # Выведет: 
print type(c1)         # Выведет: 
print type(c2)         # Выведет: 
print type(c3)         # Выведет: 
Далее...

Множественное наследование в Python

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

Множественное наследование

class Class1:         # Базовый класс для класса Class2
    def f_func1(self):
        print "Метод f_func1() класса Class1"
 
class Class2(Class1): # Класс Class2 наследует класс Class1
    def f_func2(self):
        print "Метод f_func2() класса Class2"
 
class Class3(Class1): # Класс Class3 наследует класс Class1
    def f_func1(self):
        print "Метод f_func1() класса Class3"
    def f_func2(self):
        print "Метод f_func2() класса Class3"
    def f_func3(self):
        print "Метод f_func3() класса Class3"
    def f_func4(self):
        print "Метод f_func4() класса Class3"
 
class Class4(Class2, Class3): # Множественное наследование
    def f_func4(self):
        print "Метод f_func4() класса Class4"
 
c1 = Class4()             # Создаем экземпляр класса Class4
c1.f_func1()              # Выведет: Метод f_func1() класса Class1
c1.f_func2()              # Выведет: Метод f_func2() класса Class2
c1.f_func3()              # Выведет: Метод f_func3() класса Class3
c1.f_func4()              # Выведет: Метод f_func4() класса Class4
Далее...

Наследование ООП Python

Наследование в Python является важным фактором для понимания принципа работы ООП. Предположим, у вас есть класс (Пример Class1). При помощи наследования мы можем создать новый класс (Например Class2), в котором будет доступ ко всем атрибутам и методам класса Class1, а также к некоторым атрибутам и методам.

Наследование

# -*- coding: utf-8 -*-
class Class1:         # Базовый класс
    def f_func1(self):
        print "Метод f_func1() класса Class1"
 
    def f_func2(self):
        print "Метод f_func2() класса Class1"
 
class Class2(Class1): # Класс Class2 наследует класс Class1
    def f_func3(self):
        print "Метод f_func3() класса Class2"
 
c1 = Class2()         # Создаем экземпляр класса Class2
c1.f_func1()          # Выведет: Метод f_func1() класса Class1
c1.f_func2()          # Выведет: Метод f_func2() класса Class1
c1.f_func3()          # Выведет: Метод f_func3() класса Class2
Как видно из примера, класс Class1 указывается внутри круглых скобок в определение класса Class2. Таким образом, класс Class2 наследует все атрибуты и методы класса Class1. Класс Class1 вызывется базовым классом ими суперклассом, а класс Class2 - производным классом или подклассом.

Далее...

__init__() и __del__() в Python

При создании экземпляра класса интерпретатор автоматически вызывает метод инициализации __init__(). В некоторых языках программирования данные методы принято называть конструктором и деструктором класса. В языке программирования PHP это будет __construct(); __destruct(). Формат метода:

def __init__(self[, <Значение1>[, <ЗначениеN>]]):
    <Выражение>
С помощью метода __init__() можно присвоить значения по умолчанию для атрибутах класса. При создании экземпляра класса начальные значения указываются после имени класса в круглых скобках:

<Экземпляр класса> = <Имя класса>(<Значение1>[, ..., <ЗначениеN>])
Пример использования метода __init__() приведен ниже:

# -*- coding: utf-8 -*-
class HexColor:
    def __init__(self):
        self.colors = {
            'red'   :   '#ff0000',
            'greed' :   '#7cfc00',
            'blue'  :   '#4169e1'
        }
 
hex_color = HexColor()
print hex_color.colors['red']   # Получим: #ff0000
 
 
# Пример 2: Удваиваем число
class DoubleMe:
    def __init__(self, number):
        self.result = number * 2
 
Double = DoubleMe(2)
print Double.result             # Получим 4
Далее...