Как обратиться к переменной класса python
Перейти к содержимому

Как обратиться к переменной класса python

  • автор:

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

Вытащить переменную без связки с Backtrader (в тестовом режиме и переменными в виде вручную заданных списков) одним из возможных методов по следующему примеру получается:

# 1 f = someClass(object) f.var1 = [1,2,3] f.var2 = 'asdf' someClass(f) 
# 2 XClass = someClass() XClass.close 

Через **kwargs тоже вытаскивается, но этот вариант даже не рассматриваю, т.к. списков очень много. Получить доступ к self.close находясь внутри класса возможно. Но принципиально нужно вытащить close как в представленном коде. Что я не так делаю?

Как правильно обращаться к переменной класса из другого класса?

Доброго времени суток!
Примерно с 2 недели назад начал изучать Python, до этого был не большой опыт программирования. Получил интересное задание от товарища, вопрос будет как раз по нему (введение дабы сразу не кидались палками 🙂 )

Вопрос состоит в следующем:
Как мне обратиться к двум переменным, а именно twist_num и choice_num (сравнение для дальнейшей работы с балансом)?

Пробовал через сеттер, ничего не вышло, в коде ниже попытался задействовать прямое обращение.
Вроде как сама IDE обращение видит и понимание, но при дальнейшей проверки кода в консоли = ноль реакции..

from random import randint class Balance(object): def __init__(self): self.money() self.input_bet() def run(self): self.input_bet = None def input_bet(self): input_bet = input('Ваша ставка: \n') try: input_bet = int(input_bet) self.input_bet = input_bet except Exception: print('Не число') def money(self) -> None: money = 10000 print("Ваш баланс:" + str(money)) #---------------------------------------------------------------------------------------- class Roulette(object): def __init__(self): self.__choice_num = None self.__twist_num = None def run(self): while True: self.input_number() self.twist_roulette() self.check_choice_num() def input_number(self) -> None: is_num = False while not is_num: number = input('Введите целое число от 0 до 36 \n') try: number = int(number) is_num = True self.choice_num = number except Exception: print('Опаньки. Что-то ты сделал не так. \n') def twist_roulette(self) -> None: self.twist_num = randint(0,1) def check_choice_num(self) -> None: if self.choice_num == self.twist_num: print('Ты победил: выпало число ' + str(self.twist_num)) return print('Ты проиграл: выпало число ' + str(self.twist_num)) #---------------------------------------------------------------------------------------- class Game: def __init__(self): self.roulette = Roulette() self.balance = Balance() def run(self): self.game_lose() self.game_won() def game_won(self): if roulette.choice_num == roulette.twist_num: print('You won!') balance = Balance() balance.run() roulette = Roulette() roulette.run() game = Game() game.run()
  • Вопрос задан более года назад
  • 1789 просмотров

2 комментария

Простой 2 комментария

Атрибуты класса и переменные экземпляра класса в Python

Переменные экземпляра класса предназначены для данных, уникальных для каждого экземпляра класса, а переменные класса (атрибуты данных класса) — для атрибутов и методов, общих для всех экземпляров класса.

Python вызывает специальный метод __init__() , который называют конструктором класса, каждый раз при создании нового экземпляра класса.

class Dog: # атрибут данных (переменная класса), # общая для всех экземпляров класса kind = 'canine' def __init__(self, name): # переменная экземпляра класса # уникальна для каждого экземпляра self.name = name >>> d = Dog('Fido') >>> e = Dog('Buddy') # переменная `kind` будет общая для # всех экземпляров объекта `Dog` >>> d.kind # 'canine' >>> e.kind # 'canine' # переменная `name` будет уникальна # для каждого из экземпляров >>> d.name # 'Fido' >>> e.name # 'Buddy' 

Как говорилось в материале «Классы в языке Python», общие данные могут иметь неожиданный эффект при использовании изменяемых объектов, таких как списки и словари. Например, список tricks (трюки, которые может делать отдельная собака) в примере ниже не следует использовать как атрибут данных/переменную класса, потому что для всех экземпляров класса Dog будет использоваться только один атрибут данных tricks :

class Dog: # ошибочное использование атрибута tricks - # переменной класса tricks = [] def __init__(self, name): self.name = name def add_trick(self, trick): self.tricks.append(trick) >>> d = Dog('Fido') >>> e = Dog('Buddy') >>> d.add_trick('roll over') >>> e.add_trick('play dead') # неожиданно разделяется всеми собаками >>> d.tricks # ['roll over', 'play dead'] 

Правильный дизайн класса должен использовать tricks не как атрибут данных класса, а как переменную экземпляра класса:

class Dog: def __init__(self, name): self.name = name # создает новый пустой список # трюков для каждой собаки self.tricks = [] def add_trick(self, trick): self.tricks.append(trick) >>> d = Dog('Fido') >>> e = Dog('Buddy') >>> d.add_trick('roll over') >>> e.add_trick('play dead') >>> d.tricks # ['roll over'] >>> e.tricks # ['play dead'] 

Если одно и то же имя атрибута встречается как в экземпляре класса, так и в самом классе, то поиск атрибута определяет приоритет экземпляра класса:

>>> class Warehouse: purpose = 'storage' region = 'west' >>> w1 = Warehouse() >>> print(w1.purpose, w1.region) # storage west >>> w2 = Warehouse() >>> w2.region = 'east' >>> print(w2.purpose, w2.region) # storage east 

На атрибуты данных класса могут ссылаться как методы, так и обычные пользователи — «клиенты» объекта. Другими словами, классы не могут использоваться для реализации чисто абстрактных типов данных. Фактически, ничто в Python не позволяет принудительно скрывать данные — все основано на соглашении.

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

В Python нет сокращений для ссылки на атрибуты данных или другие методы изнутри методов. Это повышает удобочитаемость методов: нет возможности путать локальные переменные и переменные экземпляра при просмотре метода.

Вместо использования привычной точечной нотации для доступа к атрибутам можно использовать встроенные функции:

  • getattr(obj, name [, default]) — для доступа к атрибуту name объекта класса obj .
  • hasattr(obj, name) — проверить, есть ли в классе obj атрибут name .
  • setattr(obj, name, value) — задать атрибут name со значением value . Если атрибут не существует, он будет создан.
  • delattr(obj, name) — удалить атрибут name из объекта класса obj .
Встроенные атрибуты класса.

Классы Python хранят встроенные атрибуты, к которым можно получить доступ как к любому другому атрибуту данных.

  • __dict__ — словарь, содержащий пространство имен класса.
  • __doc__ — строка документации класса. None если, документация отсутствует.
  • __name__ — имя класса.
  • __module__ — имя модуля, в котором определяется класс.
  • __bases__ — кортеж, содержащий базовые классы, в порядке их появления. Кортеж будет пустым, если наследование не было.
  • __mro__ — Порядок разрешения методов в множественном наследовании.

Где хранятся атрибуты класса и экземпляра класса?

Python не был бы Python без четко определенного и настраиваемого поведения атрибутов. Атрибуты в Python хранятся в магическом методе с именем __dict__ . Получить доступ к нему можно следующим образом:

class MyClass: class_attr = "Class" def __init__(self): self.instance_attr = "Instance" >>> my_object = MyClass() # атрибут экземпляра класса >>> my_object.__dict__ # # атрибут экземпляра класса >>> MyClass.__dict__['class_attr'] # 'Class' >>> my_object.class_attr 'Class' >>> my_object.instance_attr 'Instance' 
  • ОБЗОРНАЯ СТРАНИЦА РАЗДЕЛА
  • Пространство имен и область видимости в классах
  • Определение классов
  • Объект класса и конструктор класса
  • Создание экземпляра класса
  • Метод экземпляра класса
  • Что такое метод класса и зачем нужен
  • Что такое статический метод в классах Python и зачем нужен
  • Атрибуты класса и переменные экземпляра класса
  • Кэширование методов экземпляра декоратором lru_cache
  • Закрытые/приватные методы и переменные класса Python
  • Наследование классов
  • Множественное наследование классов
  • Абстрактные классы
  • Перегрузка методов в классе Python
  • Что такое миксины и как их использовать
  • Класс Python как структура данных, подобная языку C
  • Создание пользовательских типов данных
  • Специальные (магические) методы класса Python
  • Базовая настройка классов Python магическими методами
  • Настройка доступа к атрибутам класса Python
  • Дескриптор класса для чайников
  • Протокол дескриптора класса
  • Практический пример дескриптора
  • Использование метода .__new__() в классах Python
  • Специальный атрибут __slots__ класса Python
  • Специальный метод __init_subclass__ класса Python
  • Определение метаклассов metaclass
  • Эмуляция контейнерных типов в классах Python
  • Другие специальные методы класса
  • Как Python ищет специальные методы в классах
  • Шаблон проектирования Фабрика и его реализация

Переменные класса и экземпляра в Python

В этой статье мы расскажем про переменные класса и экземпляра в Python. Мы разберем, чем они отличаются и как с ними работать.

Объектно-ориентированное программирование позволяет использовать переменные на уровне класса или на уровне экземпляра класса. Переменные – это, по сути, символы, заменяющие значение, которое вы используете в программе.

На уровне класса переменные называются переменными класса, на уровне экземпляра – переменными экземпляра.

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

Одним из принципов разработки программного обеспечения является принцип DRY (Don’t repeat yourself), который означает «Не повторяйся». Этот принцип направлен на ограничение повторов (дублирования) в коде. Объектно-ориентированное программирование придерживается принципа DRY, поскольку он снижает избыточность.

Для начала

У вас должен быть установлен Python 3 и настроена среда программирования на вашем компьютере или сервере, подходящая для вашей операционной системы (Ubuntu, CentOS, Debian и т.д.)

Переменные класса в Python

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

Переменные класса определяются вне всех методов. Обычно они размещаются прямо под заголовком класса, перед методом конструктора и другими методами.

Примечание. Чтобы следовать примерам кода в этом руководстве, откройте интерактивную оболочку Python в своей локальной системе, выполнив команду python3 . Затем вы можете копировать, вставлять или редактировать примеры, добавляя код после символов >>> .

Сама по себе переменная класса выглядит следующим образом:

class Shark: animal_type = "fish"

Здесь переменной animal_type присвоено значение «fish» .

Мы можем создать экземпляр класса Shark (назовем его new_shark ) и вывести переменную, используя точечную нотацию:

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). В этой программе есть строки ( animal_type и location ) и целое число ( followers ). Давайте снова запустим программу с помощью команды python shark.py и просмотрим на результат:

# Output fish ocean 5

Экземпляр new_shark имеет доступ ко всем переменным класса и может выводить их при запуске программы.

Переменные класса позволяют нам определять переменные при построении класса. Затем эти переменные и связанные с ними значения становятся доступными для каждого экземпляра класса.

Переменные экземпляра класса в Python

Переменные экземпляра принадлежат экземплярам класса. Это означает, что для каждого объекта или экземпляра класса переменные экземпляра различны.

В отличие от переменных класса, переменные экземпляра определяются внутри методов.

Например, в приведенном ниже коде переменные класса Shark name и age являются переменными экземпляра:

class Shark: def __init__(self, name, age): self.name = name self.age = age

При создании объекта класса Shark нам нужно определить эти переменные, которые передаются как параметры в методе конструктора или другом методе.

class Shark: def __init__(self, name, age): self.name = name self.age = age new_shark = Shark("Sammy", 5)

Так же, как и в случае с переменными класса, мы можем вывести переменные экземпляра в консоль:

class Shark: def __init__(self, name, age): self.name = name self.age = age new_shark = Shark("Sammy", 5) print(new_shark.name) print(new_shark.age)

Когда мы запустим указанную выше программу, используя python shark.py , мы получим следующий вывод:

# Output Sammy 5

Полученный нами вывод состоит из значений переменных, которые мы инициализировали для экземпляра new_shark .

Давайте создадим еще один объект класса Shark под названием stevie :

class Shark: def __init__(self, name, age): self.name = name self.age = age new_shark = Shark("Sammy", 5) print(new_shark.name) print(new_shark.age) stevie = Shark("Stevie", 8) print(stevie.name) print(stevie.age) # Output: # Sammy # 5 # Stevie # 8

Объект stevie , как и объект new_shark , передает параметры, специфичные для данного конкретного экземпляра класса Shark , чтобы присвоить значения переменным экземпляра.

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

Работа с переменными класса и экземпляра одновременно

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

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()

Когда мы запустим программу, используя python shark.py , мы получим следующий результат:

# Output Sammy ocean Stevie This user has 77 followers fish

Здесь мы использовали переменные класса и экземпляра в двух объектах класса Shark : sammy и stevie .

Заключение

В объектно-ориентированном программировании переменные на уровне класса называются переменными класса, а на уровне объекта – переменными экземпляра класса.

Это различие позволяет нам использовать переменные класса для инициализации объектов с определенным значением, присвоенным переменным, а переменные экземпляра — чтобы каждый объект мог иметь свои переменные.

Использование переменных, относящихся к классу или экземпляру, помогает придерживаться принципа DRY. То есть способствует уменьшению повторов в коде.

От редакции Pythonist. Рекомендуем также почитать статью «Чем отличаются методы класса, статические и «простые» методы».

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *