Знакомство с классами в python
Содержание:
- Python Tutorial
- Использования функции в цикле while
- Создание объектов
- Давайте попрактикуемся
- Переменные класса в Python
- 1.1. Создание словаря на Python.
- Метод конструктора
- Список словарей в Python.
- 2.2. Перебор всех ключей в словаре методом keys().
- Встроенные функции классов Python
- Встроенные функции
- Работа с переменными класса и экземпляра одновременно
- Class Inheritance
- Объекты
- Should a Line Break Before or After a Binary Operator?
- Возвращаемое значение в функции на Python
- Полиморфизм в Python
- Accessing Attributes
- Indentation
- Операторы перегрузки
- Обзор терминологии ООП
- Заключение
Python Tutorial
Python HOMEPython IntroPython Get StartedPython SyntaxPython CommentsPython Variables
Python Variables
Variable Names
Assign Multiple Values
Output Variables
Global Variables
Variable Exercises
Python Data TypesPython NumbersPython CastingPython Strings
Python Strings
Slicing Strings
Modify Strings
Concatenate Strings
Format Strings
Escape Characters
String Methods
String Exercises
Python BooleansPython OperatorsPython Lists
Python Lists
Access List Items
Change List Items
Add List Items
Remove List Items
Loop Lists
List Comprehension
Sort Lists
Copy Lists
Join Lists
List Methods
List Exercises
Python Tuples
Python Tuples
Access Tuples
Update Tuples
Unpack Tuples
Loop Tuples
Join Tuples
Tuple Methods
Tuple Exercises
Python Sets
Python Sets
Access Set Items
Add Set Items
Remove Set Items
Loop Sets
Join Sets
Set Methods
Set Exercises
Python Dictionaries
Python Dictionaries
Access Items
Change Items
Add Items
Remove Items
Loop Dictionaries
Copy Dictionaries
Nested Dictionaries
Dictionary Methods
Dictionary Exercise
Python If…ElsePython While LoopsPython For LoopsPython FunctionsPython LambdaPython ArraysPython Classes/ObjectsPython InheritancePython IteratorsPython ScopePython ModulesPython DatesPython MathPython JSONPython RegExPython PIPPython Try…ExceptPython User InputPython String Formatting
Использования функции в цикле while
Функции могут вызываться в циклах while где угодно. Приведем пример цикла while, где у посетителя запрашивают имя и фамилию, а с помощью функции form_name возвращается отформатированное имя и фамилия с приветствием:
def form_name(first_name, last_name):
«»»Возвращает отформатированное полное имя»»»
full_name = «{first_name} {last_name}»
return full_name.
while True:
print(«Введите ‘x’ если хотите завершить программу»)
first_name = («Введите ваше имя: «)
first_name == ‘x’:
break
last_name = («Введите вашу фамилию: «)
last_name == ‘x’:
break
formatted_name = form_name(first_name, last_name)
print(«Добрый день {formatted_name}!»)
В данном примере в цикле whle запрашивается имя и фамилия и с помощью функции form_name возвращается отформатированное полное имя и записывается в переменную formatted_name. А затем уже с помощью функции данные выводятся на экран.
Создание объектов
# Create an object of the class person1 = Person("Richard", 23) #Create another object of the same class person2 = Person("Anne", 30) #call member methods of the objects person1.showAge() person2.showName()
Создание объектов в Python довольно простое. Сначала вы указываете имя нового объекта, за которым следует оператор присваивания и имя класса с параметрами (как определено в конструкторе).
Помните, что количество и тип параметров должны быть совместимы с параметрами, полученными в функции-конструкторе.
Когда объект создан, могут быть вызваны методы-члены и доступны атрибуты-члены (при условии, что они доступны).
#print the name of person1 by directly accessing the ‘name’ attribute print(person1.name)
Давайте попрактикуемся
- obj.method()
- obj.atr
- надо определить класс
- создать объект
- обратиться к каждому из атрибутов, записав туда кастомные данные
- обратиться к каждому объекту, передав туда кастомные аргументы
на самом деле инициализатора, но мы в этой статье не будем углубляться в разницуВажно:
- метод __init__(), как и другие методы класса должен принимать как минимум 1 аргумент self
- к аргументам объекта можно обращаться из метода как аргументам self (например, self.arg)
- Если аргумент создаётся конструктором __init__, то его не нужно описывать в классе как отдельную переменную
Давайте создадим чуть более осмысленный класс.Интересный эффект, который можно заметить — после пересоздания класса ранее созданные объекты не меняют своего поведения.
Геттеры и Сеттеры
- сеттер — setColor — проверяет, что передаётся строка и записывает её в атрибут color экземпляра. Если передан другой тип данных, возвращает ошибку.
- геттер — getColor — возвращает значение атрибута color текущего экземпляра
Наследование
- атрибуты: число ног, имя, возраст.
- методы: геттеры и сеттеры
- атрибуты: имя и т.п.
- методы: «говорение» (мяу) и т.п.
Такие классы ещё иногда называются «примесью», дальше станет понятно почему.Удивительно, но это работает.
- наследник получает все методы и атрибуты обоих родителей.
- если у нескольких родителей есть одноимённые методы, то автоматически наследник получит методы того, кто раньше в списке (в нашем случае раньше был гео маркер, поэтому конструктор был унаследован от него, а не от организации).
Наследование от нескольких родителей иногда считается сомнительной практикой, будьте с ним аккуратны.
Переменные класса
- в атрибуте ID каждого объекта хранится его уникальный порядковый номер
- в переменной tag класса хранится число созданных объектов (тут надо быть осторожнее, так как возможно мы захотим уменьшать это число при удалении объекта).
Переменные класса в Python
Переменные класса определяются в конструкторе класса. Поскольку они принадлежат самому классу, переменные класса разделяются всеми экземплярами класса. Поэтому они, как правило, будут иметь одинаковое значение для каждого экземпляра. Исключение — если вы используете переменную класса для инициализации переменной.
Переменные класса определяются вне всех методов. Обычно они размещаются прямо под заголовком класса, перед методом конструктора и другими методами.
Примечание. Чтобы следовать примерам кода в этом руководстве, откройте интерактивную оболочку Python в своей локальной системе, выполнив команду . Затем вы можете копировать, вставлять или редактировать примеры, добавляя код после символов .
Сама по себе переменная класса выглядит следующим образом:
class Shark: animal_type = "fish"
Здесь переменной присвоено значение .
Мы можем создать экземпляр класса (назовем его ) и вывести переменную, используя точечную нотацию:
class Shark: animal_type = "fish" new_shark = Shark() print(new_shark.animal_type)
Запустим нашу программу:
И получим следующий результат:
Программа возвращает значение нашей переменной.
Теперь давайте добавим ещё несколько переменных класса и выведем их:
class Shark: animal_type = "fish" location = "ocean" followers = 5 new_shark = Shark() print(new_shark.animal_type) print(new_shark.location) print(new_shark.followers)
Как и любая другая переменная, переменные класса могут содержать данные любого типа (из доступных в Python). В этой программе есть строки ( и ) и целое число (). Давайте снова запустим программу с помощью команды и просмотрим на результат:
# Output fish ocean 5
Экземпляр имеет доступ ко всем переменным класса и может выводить их при запуске программы.
Переменные класса позволяют нам определять переменные при построении класса. Затем эти переменные и связанные с ними значения становятся доступными для каждого экземпляра класса.
1.1. Создание словаря на Python.
Для создания словаря заключите в фигурные скобки {} список пар «ключ-значение», разделенных запятыми, в форме ключ: значение. Значением может быть число, список, строка и даже другой словарь. В примере ниже хранится информация об одном автомобиле.
>>> car_1 = {‘brand’: ‘bmw’, ‘type’: ‘седан’, ‘mileage’: 58135}
>>> print(car_1){‘brand’: ‘bmw’, ‘type’: ‘седан’, ‘mileage’: 58135}
В данном примере ключом является ‘марка’, а значение ‘bmw’. Затем через запятую идет следующая пара ключ-значение и так далее. Если вы укажете ключ, то Python вернет значение, связанное с этим ключом. Ключ от значения всегда отделяется двоеточием.
Метод конструктора
Для инициализации данных используется метод конструктора. Он запускается, когдасоздается объект класса. Он также известен, как метод __init__. Это будет первое определение класса:
classShark: def__init__(self): print("This is the constructor method.")
Если в наш пример добавить к классу Shark указанный метод__init__, программа выведет следующее без внесения изменений в экземпляр sammy:
Вывод This is the constructor method. The shark is swimming. The shark is being awesome.
Это связано с тем, что метод конструктора инициализируется автоматически. Вы должны использовать его для любой инициализации в объектах класса.
Создадим метод конструктора, который использует переменную name. Ее мы применим для присвоения имен объектам. Мы передадим name в качестве параметра и зададим self.name, равное name:
shark.py
classShark: def__init__(self, name): self.name = name
Можно изменить строки в функциях, чтобы ссылаться на имена:
shark.py
classShark: def__init__(self, name): self.name = name defswim(self): # Ссылка на имя print(self.name + " is swimming.") defbe_awesome(self): # Ссылка на имя print(self.name + " is being awesome.")
Также мы можем установить имя объекта Shark sammy равным «Sammy», передав его, как параметр класса Shark:
shark.py
classShark: def__init__(self, name): self.name = name defswim(self): print(self.name + " is swimming.") defbe_awesome(self): print(self.name + " is being awesome.") defmain(): # Устанавливаем имя объекта Shark sammy = Shark("Sammy") sammy.swim() sammy.be_awesome() if __name__ == "__main__": main()
Теперь запустим программу:
python shark.py Вывод Sammy is swimming. Sammy is being awesome.
Имя, которое мы передали объекту, выводится. Мы определили метод __init__ с именем параметра (вместе с ключевым словом self) и передали переменную внутри метода.
Метод конструктора инициализируется автоматически, поэтому его не нужно явно вызывать. Достаточно при создании экземпляра класса передать аргументы в круглых скобках, следующих за именем класса.
Если нужно было бы добавить еще один параметр, например возраст, мы могли сделать это, передав его методу __init__:
classShark: def__init__(self, name, age): self.name = name self.age = age
При создании объекта sammy можно передать возраст Сэмми:
sammy = Shark("Sammy", 5)
Чтобы использовать параметр age, также нужно будет создать метод в классе. Методы конструктора позволяют инициализировать определенные атрибуты объекта.
Список словарей в Python.
В Python можно сохранить множество словарей в списки или список сделать значением элемента словаря. Создание таких сложных структур называется вложениями. Можно вложить не ограниченное количество словарей в список.
>>> car_1 = {‘brand’: ‘bmw’, ‘type’: ‘седан’, ‘mileage’: 58135, ‘color’: ‘белый’}
>>> car_2 = {‘brand’: ‘ford’, ‘type’: ‘седан’, ‘mileage’: 1205, ‘color’: ‘черный’}
>>> car_3 = {‘brand’: ‘audi’, ‘type’: ‘седан’, ‘mileage’: 65489, ‘color’: ‘белый’}
Далее создаем пустой список и добавляем в него словари.
>>> cars = []
>>> cars.append(car_1)
>>> cars.append(car_2)
>>> cars.append(car_3)
>>> print(cars)
Для удобства чтения кода можно вывести элементы списка с помощью цикла for.
>>> for car in cars:
… print(car)
…{‘brand’: ‘bmw’, ‘type’: ‘седан’, ‘mileage’: 58135, ‘color’: ‘белый’}
{‘brand’: ‘ford’, ‘type’: ‘седан’, ‘mileage’: 1205, ‘color’: ‘черный’}
{‘brand’: ‘audi’, ‘type’: ‘седан’, ‘mileage’: 65489, ‘color’: ‘белый’}
В процессе работы может понадобиться изменить какой-либо элемент. Для этого также можно воспользоваться циклом for и командой if-else. К примеру, нам нужно изменить пробег и цвет автомобиля Bmw.
>>> for car in cars:
… if car == ‘bmw’:
… car = 100000
… car = ‘зеленый’
… print(car)
… else:
… print(car)
…{‘brand’: ‘bmw’, ‘type’: ‘седан’, ‘mileage’: 100000, ‘color’: ‘зеленый’}
{‘brand’: ‘ford’, ‘type’: ‘седан’, ‘mileage’: 1205, ‘color’: ‘черный’}
{‘brand’: ‘audi’, ‘type’: ‘седан’, ‘mileage’: 65489, ‘color’: ‘белый’}
В результате Python перебирает список и проверяет условия, если в паре ключ: значение появляется автомобиль Bmw, то для него меняются элементы, для всех остальных ничего не изменяется.
2.2. Перебор всех ключей в словаре методом keys().
Метод keys() удобен если вы собираетесь работать с ключами в словаре. Переберем словарь и выведем все ключи в нем:
>>> year = {‘январь’: 31, ‘февраль’: 28, ‘март’: 31, ‘апрель’: 30}
>>> for key in year.keys():
… print(key)
…январь
февраль
март
апрель
В Python перебор ключей используется по умолчанию при переборе словаря. Две записи ниже дают один и тот же результат.
>>> for key in year.keys():
>>> for key in year:
Явный вызов метода keys() может упростить чтение вашего кода.
Начиная с Python 3.7 перебор содержимого словаря возвращает элементы в том порядке, в каком они вставлялись. Один из способов перебрать элементы в определенном порядке, вызвать функцию sorted().
>>> for key in sorted(year.keys()):
… print(key)
…апрель
март
февраль
январь
В результате ключи сортируются по алфавиту.
Встроенные функции классов Python
Встроенные функции, определенные в классе, описаны в следующей таблице.
SN | Функция | Описание |
---|---|---|
1 | getattr(obj,name,default) | Используется для доступа к атрибуту объекта. |
2 | setattr(obj, name,value) | Она используется для установки определенного значения для определенного атрибута объекта. |
3 | delattr (obj, name) | Необходима для удаления определенного атрибута. |
4 | hasattr (obj, name) | Возвращает истину, если объект содержит определенный атрибут. |
Пример
class Student: def __init__(self, name, id, age): self.name = name self.id = id self.age = age # creates the object of the class Student s = Student("John", 101, 22) # prints the attribute name of the object s print(getattr(s, 'name')) # reset the value of attribute age to 23 setattr(s, "age", 23) # prints the modified value of age print(getattr(s, 'age')) # prints true if the student contains the attribute with name id print(hasattr(s, 'id')) # deletes the attribute age delattr(s, 'age') # this will give an error since the attribute age has been deleted print(s.age)
Выход:
John 23 True AttributeError: 'Student' object has no attribute 'age'
Встроенные функции
print (x, sep = 'y') печатает x объектов, разделенных y
len (x) возвращает длину x (s, L или D)
min (L ) возвращает минимальное значение в L
max (L) возвращает максимальное значение в L
sum (L) возвращает сумму значений в диапазоне L
range(n1,n2,n) (n1, n2, n) возвращает последовательность чисел от n1 до n2 с шагом n
abs (n) возвращает абсолютное значение n
round (n1, n) возвращает число n1, округленное до n цифр
type (x) возвращает тип x (string, float, list, dict…)
str (x) преобразует x в string
list (x) преобразует x в список
int (x) преобразует x в целое число
float (x) преобразует x в число с плавающей запятой
help (s) печатает справку о x
map (function, L) Применяет функцию к значениям в L
Работа с переменными класса и экземпляра одновременно
Переменные класса и переменные экземпляра часто используются одновременно. Поэтому давайте рассмотрим такой пример, используя созданный нами класс . Комментарии в программе описывают каждый этап процесса.
class Shark: # Переменные класса animal_type = "fish" location = "ocean" # Метод-конструктор с переменными экземпляра name и age def __init__(self, name, age): self.name = name self.age = age # Метод с переменной экземпляра followers def set_followers(self, followers): print("This user has " + str(followers) + " followers") def main(): # Первый объект. Установка переменных экземпляра метода-конструктора sammy = Shark("Sammy", 5) # Вывод переменной экземпляра name print(sammy.name) # Вывод переменной класса location print(sammy.location) # Второй объект stevie = Shark("Stevie", 8) # Вывод переменной экземпляра name print(stevie.name) # Использование метода set_followers и передача переменной экземпляра followers stevie.set_followers(77) # Вывод переменной класса animal_type print(stevie.animal_type) if __name__ == "__main__": main()
Когда мы запустим программу, используя , мы получим следующий результат:
# Output Sammy ocean Stevie This user has 77 followers fish
Здесь мы использовали переменные класса и экземпляра в двух объектах класса : и .
Class Inheritance
Instead of starting from scratch, you can create a class by deriving it from a preexisting class by listing the parent class in parentheses after the new class name.
The child class inherits the attributes of its parent class, and you can use those attributes as if they were defined in the child class. A child class can also override data members and methods from the parent.
Syntax
Derived classes are declared much like their parent class; however, a list of base classes to inherit from is given after the class name −
class SubClassName (ParentClass1): 'Optional class documentation string' class_suite
Example
#!/usr/bin/python class Parent: # define parent class parentAttr = 100 def __init__(self): print "Calling parent constructor" def parentMethod(self): print 'Calling parent method' def setAttr(self, attr): Parent.parentAttr = attr def getAttr(self): print "Parent attribute :", Parent.parentAttr class Child(Parent): # define child class def __init__(self): print "Calling child constructor" def childMethod(self): print 'Calling child method' c = Child() # instance of child c.childMethod() # child calls its method c.parentMethod() # calls parent's method c.setAttr(200) # again call parent's method c.getAttr() # again call parent's method
When the above code is executed, it produces the following result −
Calling child constructor Calling child method Calling parent method Parent attribute : 200
Similar way, you can drive a class from multiple parent classes as follows −
class A: # define your class A ..... class B: # define your class B ..... class C(A, B): # subclass of A and B .....
You can use issubclass() or isinstance() functions to check a relationships of two classes and instances.
-
The issubclass(sub, sup) boolean function returns true if the given subclass sub is indeed a subclass of the superclass sup.
-
The isinstance(obj, Class) boolean function returns true if obj is an instance of class Class or is an instance of a subclass of Class
Объекты
Объект – это экземпляр класса. Используйте класс Shark для создания объекта jimmy.
Вы инициализировали объект jimmy как экземпляр класса.
Теперь добавьте методы класса Shark в объект jimmy:
Теперь объект jimmy, созданный на основе класса Shark, использует методы swim() и be_awesome(), которые были вызваны с помощью оператора-точки. Этот оператор позволяет сослаться на атрибут объекта. В этом случае атрибут является методом, и он вызывается со скобками, как любая обычная функция.
Поскольку ключевое слово self является параметром методов, как определено в классе Shark, объект jimmy передается методам. Параметр self позволяет методам ссылаться на атрибуты объекта.
При вызове методов объект jimmy автоматически передается с помощью оператора-точки.
Добавьте объект в файл shark.py:
Запустите программу:
Should a Line Break Before or After a Binary Operator?
For decades the recommended style was to break after binary operators.
But this can hurt readability in two ways: the operators tend to get
scattered across different columns on the screen, and each operator is
moved away from its operand and onto the previous line. Here, the eye
has to do extra work to tell which items are added and which are
subtracted:
# Wrong: # operators sit far away from their operands income = (gross_wages + taxable_interest + (dividends - qualified_dividends) - ira_deduction - student_loan_interest)
To solve this readability problem, mathematicians and their publishers
follow the opposite convention. Donald Knuth explains the traditional
rule in his Computers and Typesetting series: «Although formulas
within a paragraph always break after binary operations and relations,
displayed formulas always break before binary operations» .
Following the tradition from mathematics usually results in more
readable code:
# Correct: # easy to match operators with operands income = (gross_wages + taxable_interest + (dividends - qualified_dividends) - ira_deduction - student_loan_interest)
Возвращаемое значение в функции на Python
Вместо вывода результата работы напрямую, функция может обработать данные и вернуть значение c помощью команды return. Значение, возвращаемое функцией, называется возвращаемым значением.
3.1. Возвращение простого значения
Напишем функцию, которая возвращает отформатированное имя и фамилию
>>> def form_name(last_name, first_name, middle_name):
… «»»Возвращает отформатированное полное имя»»»
… full_name = «{last_name} {first_name} {middle_name}»
… return full_name.
…
>>> poet = form_name(‘пушкин’, ‘александр’, ‘сергеевич’)
>>> print(poet)Пушкин Александр Сергеевич
Функция form_name получает в параметрах имя, фамилию и отечество, далее объединяет эти имена и сохраняет их в переменной full_name. Завершив выполнение, функция возвращает управление в точку вызова с помощью команды return, то есть в строку кода, которая вызывала функцию.
Предположим, что мы не знаем отчество человека, для передачи его фукции параметру middle_name. В связи с этим удобно заранее сделать в функции необязательный аргумент. Присвоим ( middle_name = «» ) пустое значение.
>>> def form_name(last_name, first_name, middle_name=»):
… «»»Возвращает отформатированное полное имя»»»
… full_name = «{last_name} {first_name} {middle_name}»
… return full_name.
…
>>> poet = form_name(‘пушкин’, ‘александр’)
>>> print(poet)Пушкин Александр
>>> poet = form_name(‘пушкин’, ‘александр’, ‘сергеевич’)
>>> print(poet)Пушкин Александр Сергеевич
С необязательным аргументом мы не получим ошибку (TypeError: form_name() missing 1 required positional argument: ‘middle_name’) в случае отсутствия на входе данных по аргументу.
3.2. Возвращение словаря
Функция может возвращать и более сложную структуру данных, например словарь или список. Напишем функцию, которая будет возвращать словарь, представляющий человека:
>>> def info_person(first_name, last_name):
… «»»Возвращает словарь с данными о человеке»»»
… person = {‘first’: first_name, ‘last’: last_name}
… return person
…
>>> musician = info_person(‘Freddie’, ‘Mercury’)
>>> print(musician){‘first’: ‘Freddie’, ‘last’: ‘Mercury’}
При вызове функции info_person получает имя и фамилию на входе и помещает их сразу в словарь, с ключами имя и фамилия. Затем с помощью команды return возвращает словарь. В будущем со словарем будет удобнее работать, мы сможем отдельно использовать имя, фамилию или другие аргументы функции.
Полиморфизм в Python
Это концепция, при которой функция может принимать несколько форм в зависимости от количества аргументов или типа аргументов, переданных функции.
В приведенном выше примере ключевое слово super используется для вызова метода родительского класса. Оба класса имеют метод show_salary. В зависимости от типа объекта, который выполняет вызов этой функции, выходные данные различаются.
Python также имеет встроенные функции, работающие с полиморфизмом. Одним из самых простых примеров является функция print в Python.
Вывод будет таким:
В приведенном выше фрагменте кода:
- Параметр конечного ключевого слова изменил работу функции print. Следовательно, «Привет!» не заканчивалось концом строки.
- len () в третьей строке возвращает int. Печать распознает тип данных и неявно преобразует его в строку и выводит его на консоль.
Accessing Attributes
You access the object’s attributes using the dot operator with object. Class variable would be accessed using class name as follows −
emp1.displayEmployee() emp2.displayEmployee() print "Total Employee %d" % Employee.empCount
Now, putting all the concepts together −
#!/usr/bin/python class Employee: 'Common base class for all employees' empCount = 0 def __init__(self, name, salary): self.name = name self.salary = salary Employee.empCount += 1 def displayCount(self): print "Total Employee %d" % Employee.empCount def displayEmployee(self): print "Name : ", self.name, ", Salary: ", self.salary "This would create first object of Employee class" emp1 = Employee("Zara", 2000) "This would create second object of Employee class" emp2 = Employee("Manni", 5000) emp1.displayEmployee() emp2.displayEmployee() print "Total Employee %d" % Employee.empCount
When the above code is executed, it produces the following result −
Name : Zara ,Salary: 2000 Name : Manni ,Salary: 5000 Total Employee 2
You can add, remove, or modify attributes of classes and objects at any time −
emp1.age = 7 # Add an 'age' attribute. emp1.age = 8 # Modify 'age' attribute. del emp1.age # Delete 'age' attribute.
Instead of using the normal statements to access attributes, you can use the following functions −
-
The getattr(obj, name) − to access the attribute of object.
-
The hasattr(obj,name) − to check if an attribute exists or not.
-
The setattr(obj,name,value) − to set an attribute. If attribute does not exist, then it would be created.
-
The delattr(obj, name) − to delete an attribute.
hasattr(emp1, 'age') # Returns true if 'age' attribute exists getattr(emp1, 'age') # Returns value of 'age' attribute setattr(emp1, 'age', 8) # Set attribute 'age' at 8 delattr(empl, 'age') # Delete attribute 'age'
Indentation
Use 4 spaces per indentation level.
Continuation lines should align wrapped elements either vertically
using Python’s implicit line joining inside parentheses, brackets and
braces, or using a hanging indent . When using a hanging
indent the following should be considered; there should be no
arguments on the first line and further indentation should be used to
clearly distinguish itself as a continuation line:
# Correct: # Aligned with opening delimiter. foo = long_function_name(var_one, var_two, var_three, var_four) # Add 4 spaces (an extra level of indentation) to distinguish arguments from the rest. def long_function_name( var_one, var_two, var_three, var_four): print(var_one) # Hanging indents should add a level. foo = long_function_name( var_one, var_two, var_three, var_four)
# Wrong: # Arguments on first line forbidden when not using vertical alignment. foo = long_function_name(var_one, var_two, var_three, var_four) # Further indentation required as indentation is not distinguishable. def long_function_name( var_one, var_two, var_three, var_four): print(var_one)
The 4-space rule is optional for continuation lines.
Optional:
# Hanging indents *may* be indented to other than 4 spaces. foo = long_function_name( var_one, var_two, var_three, var_four)
When the conditional part of an if-statement is long enough to require
that it be written across multiple lines, it’s worth noting that the
combination of a two character keyword (i.e. if), plus a single space,
plus an opening parenthesis creates a natural 4-space indent for the
subsequent lines of the multiline conditional. This can produce a visual
conflict with the indented suite of code nested inside the if-statement,
which would also naturally be indented to 4 spaces. This PEP takes no
explicit position on how (or whether) to further visually distinguish such
conditional lines from the nested suite inside the if-statement.
Acceptable options in this situation include, but are not limited to:
# No extra indentation. if (this_is_one_thing and that_is_another_thing): do_something() # Add a comment, which will provide some distinction in editors # supporting syntax highlighting. if (this_is_one_thing and that_is_another_thing): # Since both conditions are true, we can frobnicate. do_something() # Add some extra indentation on the conditional continuation line. if (this_is_one_thing and that_is_another_thing): do_something()
(Also see the discussion of whether to break before or after binary
operators below.)
The closing brace/bracket/parenthesis on multiline constructs may
either line up under the first non-whitespace character of the last
line of list, as in:
my_list = result = some_function_that_takes_arguments( 'a', 'b', 'c', 'd', 'e', 'f', )
or it may be lined up under the first character of the line that
starts the multiline construct, as in:
Операторы перегрузки
Предположим, что вы создали класс Vector для представления двумерных векторов. Что произойдет, когда вы добавите оператор «плюс»? Скорее всего, Python будет кричать на вас.
Однако вы можете определить метод __add__ в вашем классе для выполнения сложения векторов, и тогда оператор плюс будет вести себя так, как ожидалось:
пример
#!/usr/bin/python class Vector: def __init__(self, a, b): self.a = a self.b = b def __str__(self): return 'Vector (%d, %d)' % (self.a, self.b) def __add__(self,other): return Vector(self.a + other.a, self.b + other.b) v1 = Vector(2,10) v2 = Vector(5,-2) print v1 + v2
Когда приведенный выше код выполняется, он дает следующий результат
Vector(7,8)
Обзор терминологии ООП
- Класс — определенный пользователем прототип для объекта, который определяет набор атрибутов, которые характеризуют любой объект класса. Атрибутами являются члены данных (переменные класса и переменные экземпляра) и методы, доступ к которым осуществляется через точечную запись.
- Переменная класса — переменная, которая используется всеми экземплярами класса. Переменные класса определены внутри класса, но вне любого из методов класса. Переменные класса используются не так часто, как переменные экземпляра.
- Член данных — переменная класса или переменная экземпляра, которая содержит данные, связанные с классом и его объектами.
- Перегрузка функций — назначение более чем одного поведения определенной функции. Выполняемая операция варьируется в зависимости от типов объектов или аргументов.
- Переменная экземпляра — переменная, которая определена внутри метода и принадлежит только текущему экземпляру класса.
- Наследование — передача характеристик класса другим классам, которые являются его производными.
- Экземпляр — индивидуальный объект определенного класса. Например, объект obj, принадлежащий классу Circle, является экземпляром класса Circle.
- Instantiation — создание экземпляра класса.
- Метод — особый вид функции, который определен в определении класса.
- Объект — уникальный экземпляр структуры данных, который определяется его классом. Объект включает в себя как члены данных (переменные класса и переменные экземпляра), так и методы.
- Перегрузка оператора — назначение более чем одной функции определенному оператору.
Заключение
В объектно-ориентированном программировании переменные на уровне класса называются переменными класса, а на уровне объекта – переменными экземпляра класса.
Это различие позволяет нам использовать переменные класса для инициализации объектов с определенным значением, присвоенным переменным, а переменные экземпляра — чтобы каждый объект мог иметь свои переменные.
Использование переменных, относящихся к классу или экземпляру, помогает придерживаться принципа DRY. То есть способствует уменьшению повторов в коде.
От редакции Pythonist. Рекомендуем также почитать статью «Чем отличаются методы класса, статические и «простые» методы».
Перевод статьи «Understanding Class and Instance Variables in Python 3».