Как обратиться к переменной, находящейся внутри класса
Вытащить переменную без связки с 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()
- Вопрос задан более года назад
- 1592 просмотра
2 комментария
Простой 2 комментария
Понимание переменных класса и экземпляра в Python 3
При изучении объектно-ориентированного программирования на Python может возникнуть несколько сложностей, когда дело доходит до разграничения переменных класса и экземпляра. В этом руководстве я объясню разницу между переменными класса и экземпляра и приведу примеры, демонстрирующие различные варианты использования.
Переменные класса и экземпляра
Во-первых, быстрый обзор, если вы новичок в объектно-ориентированном программировании. Класс — это шаблон для создания объектов, а экземпляр — это сам объект. Классы часто представляют что-то в реальном мире, так что представьте, хотите ли вы создать класс, списка студентов. Вы можете создать класс с именем Student, который представляет собой шаблон, который определяет различные атрибуты студента. Таким образом, каждый студент является экземпляром класса Student.
При работе с данными любого типа некоторые атрибуты будут уникальными, а некоторые будут общими. Рассмотрим пример с учениками: у каждого учащегося в этом классе один и тот же номер и один учитель, но у каждого из них есть уникальное имя, возраст и любимый предмет.
Переменные класса
Переменные класса обычно являются переменными, которые являются общими для всех экземпляров. И они определены так:
class Student: teacher = 'Mrs. Jones' # переменная класса
Каждый экземпляр класса будет иметь одинаковое значение для этих переменных:
tom = Student() susan = Student() print(tom.teacher) >> "Mrs. Jones" print(susan.teacher) >> "Mrs. Jones"
Переменные экземпляра
Переменные экземпляра (также называемые атрибутами данных) уникальны для каждого экземпляра класса и определяются в методе класса, например:
class Student: teacher = 'Mrs. Jones' # переменная класса def __init__(self, name): self.name = name # переменная экземпляра
Посмотрите, как каждый экземпляр теперь содержит уникальное значение name:
tom = Student('Tom') susan = Student('Susan') print(tom.name) >> "Tom" print(susan.name) >> "Susan"
Резюме
Это был только базовый обзор переменных класса и экземпляра. Мы углубимся в следующие шаги, но наиболее важный вывод заключается в том, что переменные класса обычно используются для значений, которые являются общими для всех экземпляров класса, в то время как переменные экземпляра используются для значений, уникальных для каждого экземпляра.
Чего ожидать от переменных класса
Переменные класса являются общими для всех экземпляров класса. Напоминаем, что они определены так:
class Student: teacher = 'Mrs. Jones'
Иными словами, переменные класса ссылаются на одно и то же место в памяти. Смотрите следующее:
tom = Student() susan = Student() id(tom.teacher) == id(susan.teacher) >> True
Функция id возвращает адрес объекта в памяти для реализации CPython.
Таким образом, с помощью функции id мы можем подтвердить, что атрибут teacher ссылается на то же место в памяти.
Изменение переменной класса
Что произойдет, если мы изменим переменную класса даже после создания экземпляров?
tom = Student() tom.teacher >> Mrs. Jones Student.teacher = 'Mr. Smith' tom.teacher >> Mr. Smith
Как и следовало ожидать, поскольку переменная teacher ссылается на общее местоположение в памяти, она также обновляется в экземпляре.
Изменение переменной экземпляра
Это, вероятно, наиболее очевидное и ожидаемое поведение, поэтому не стесняйтесь пропустить этот шаг. Но я все же покажу несколько примеров для полноты.
Рассмотрим наш класс Student с переменными класса и экземпляра:
class Student: teacher = 'Mrs. Jones' def __init__(self, name): self.name = name
Мы видим, что каждый экземпляр класса имеет уникальный адрес памяти для имени:
tom = Student('Tom') susan = Student('Susan') id(tom.name) == id(susan.name) >> False
Как и следовало ожидать, обновление атрибута name в одном экземпляре не влияет на другой:
tom.name >> Tom susan.name >> Susan tom.name = 'Thomas' tom.name >> Thomas susan.name >> Susan
Переменные экземпляра переопределяют переменные класса (и методы)
Важно отметить, что переменные экземпляра (или атрибуты данных) переопределяют переменные класса.
tom = Student() susan = Student() id(tom.teacher) == id(susan.teacher) >> True
Что произойдет, если мы изменим атрибут teacher прямо в одном из случаев:
tom.teacher = 'Mr. Clark'
Это важно отметить: переменные экземпляров не нужно объявлять, они создаются всякий раз, когда им присваиваются, а переменные экземпляра переопределяют переменные класса. Это означает, что в экземпляре Tom teacher больше не ссылается на переменную класса, а на вновь созданную переменную экземпляра.
И, естественно, экземпляр Сьюзен не затронут:
tom.teacher >> Mr. Clark susan.teacher >> Mrs. Jones
Надеюсь, вы видите, как такое поведение может привести к путанице. По этой причине важно сохранять организованные имена переменных. Если переменная объявлена как переменная класса, она (обычно) не должна быть переопределена. Переменные экземпляра могут быть определены в очевидных местах, например, метод __init__. Часто хорошо придумать соглашение об именовании переменных. Например, методы класса должны быть глаголами, существительными переменных класса и существительными переменных экземпляра с префиксом «_».
Использование изменяемых объектов в качестве переменных класса
В связи с предыдущим шагом, будьте осторожны при использовании изменяемых объектов в качестве переменных класса. Вы можете быть удивлены поведением.
Представьте, что мы хотим получить список результатов тестов студента. Мы могли бы составить такой класс:
class Student: teacher = 'Mrs. Jones' test_scores = [] def __init__(self, name): self.name = name def add_score(self, score): self.test_scores.append(score)
У нас есть переменная класса для хранения баллов, и у нас есть метод класса для добавления баллов. Теперь давайте добавим несколько баллов.
tom = Student('Tom') susan = Student('Susan') tom.add_score(90) susan.add_score(100)
Можете ли вы угадать, какую ошибку мы только что сделали?
tom.test_scores >> [90, 100]
Да, test_scores — это переменная класса, а не переменная экземпляра. Каждый экземпляр просто добавляет значения в переменную класса. Мы действительно хотим, чтобы каждый экземпляр содержал свой собственный список test_scores.
Так что лучший класс может выглядеть так:
class Student: teacher = 'Mrs. Jones' def __init__(self, name): self.name = name self.test_scores = [] def add_score(self, score): self.test_scores.append(score)
И теперь наша проблема решена!
Заключение
Надеюсь, вы узнали разницу между переменными класса и экземпляра и что ожидать от каждой из них. Если я что-то упустил в этом руководстве или у вас есть отличные примеры путаницы переменных класса и экземпляра, пожалуйста, прокомментируйте ниже. Я был бы рад добавить их в это руководство!
Переменные класса и экземпляра в Python 3
В объектно-ориентированном программировании переменные можно использовать на уровне класса или объекта. Переменная – это символ, который заменяет какое-либо значение в программе.
Если какая-либо переменная будет иметь одно и то же значение во всех объектах программы, её можно определить на уровне класса. Если значение переменной будет изменяться в зависимости от объекта, такую переменную нужно определить на уровне экземпляра (объекта).
DRY (don’t repeat yourself, рус. не повторяйся) – это принцип программирования, который подразумевает снижение повторений кода в рамках программы.
Данное руководство научит пользоваться переменными класса и объектными переменными (или переменными экземпляра) в объектно-ориентированном программировании в Python.
Переменные класса
Переменные класса определяются на уровне класса и применяются ко всем объектам, созданным на его основе. Такая переменная, как правило, имеет одно и то же значение внутри всех объектов на основе этого класса (если только она не используется для инициализации переменной).
Переменная класса, определяемая вне метода, как правило, пишется под заголовком класса и перед методом конструктора и другими методами.
Переменная класса выглядит так:
class Shark:
animal_type = «fish»
Создайте тестовую программу shark.py. В этом файле можно создать экземпляр класса Shark (например, new_shark) и вывести переменную с помощью точечной нотации:
class Shark:
animal_type = «fish»
new_shark = Shark()
print(new_shark.animal_type)
python shark.py
fish
Программа отобразила значение переменной.
Добавьте в класс больше переменных и отобразите их:
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, переменные класса могут содержать любой тип данных. В данной программе переменные будут содержать строки и целые числа.
Снова запустите программу:
На экране появится:
Объект new_shark имеет доступ ко всем переменным класса и может отобразить их на экране.
Объектные переменные
Объектные переменные имеют индивидуальное значение внутри того или иного объекта.
В отличие от переменных класса, объектные переменные определяются внутри метода.
К примеру, в классе 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(«Wally», 5)
Как и переменные класса, объектные переменные можно отобразить:
class Shark:
def __init__(self, name, age):
self.name = name
self.age = age
new_shark = Shark(«Wally», 5)
print(new_shark.name)
print(new_shark.age)
python shark.py
Wally
5
Полученный результат состоит из значений переменных, которые были инициализированы для объекта new_shark.
Создайте ещё один объект класса Shark (например, stevie):
class Shark:
def __init__(self, name, age):
self.name = name
self.age = age
new_shark = Shark(«Wally», 5)
print(new_shark.name)
print(new_shark.age)
stevie = Shark(«Stevie», 8)
print(stevie.name)
print(stevie.age)
Объект stevie, как и объект new_shark, передает индивидуальные параметры экземпляра класса 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():
# Первый объект определяет объектные переменные метода конструктора
wally = Shark(«Wally», 5)
# Отображение объектной переменной name
print(wally.name)
# Отображение переменной класса location
print(wally.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()
Вы получите такой результат:
Wally
ocean
Stevie
This user has 77 followers
fish
Заключение
В объектно-ориентированном программировании переменные на уровне класса называются переменными класса, а переменные на уровне объекта называются объектными переменными.
Переменные класса можно использовать для инициализации объектов с определенным значением, присвоенным переменным. Объектные переменные имеют индивидуальное значение внутри каждого объекта.
Это позволяет разрабатывать программы по принципу DRY и уменьшить повторение кода.