Найти - Пользователи
Полная версия: Использование шаблона при обращении к объекту
Начало » Python для новичков » Использование шаблона при обращении к объекту
1 2
m1r42
Здоровья, всем!

Интересует такой вопрос. Возможно ли при обращении к объектами использовать шаблон, чтобы в динамике их менять. Допустим есть такой код:
 class class1(object):
    def __init__(self):
        self.a = ""
x = class1()
x.a = "first"
y = class1()
y.a = "second"
check = False
for i in range(0,10):
    check = not check
    if check == True:
        q = x.a
        print(q)
    if check == False:
        q = y.a
        print(q)
Из кода видно, что блок:
         q = x.a
        print(q)
идентичен блоку:
         q = y.a
        print(q)
отличие лишь в объектах к которым обращается программа.
Собственно вопрос в том можно ли вместо объекта установить некий шаблон, а в начале цикла только менять имя x на y и наоборот?
m1r42
Не знаю правильно это или нет, но вот такой код работает:
 class class1(object):
    def __init__(self):
        self.a = ""
x = class1()
x.a = "first"
y = class1()
y.a = "second"
check = False
c = x
for i in range(0,10):
    check = not check
    if check == True:
        c = x
    if check == False:
        c = y
        
    q = c.a
    print(q)
m1r42
Более того наблюдаю такую картину, что экземпляр c, являясь потомком любого из экземпляров x или y, может менять их переменные. Т.е. изменяя переменную a в экземпляре c , автоматически меняем переменную a в любом из предков x либо y. Хочу услышать мнение экспертов по этому вопросу. Типа, почему я не прав и почему так делать нельзя. Люблю критику в стиле “ты ничего не понимаешь в ООП, надо тебе вернуться в процедурную парадигму программирования ” . Шутка. Хочу понять, возможно ли такое наследование и какими проблемами оно грозит в дальнейшем? Спасибо за ответ.
xam1816
m1r42
Хочу понять, возможно ли такое наследование
вы путаете наследование с присвоением
m1r42
чтобы в динамике их менять.
  
import time
 
class MyClass:
    def __init__(self, a):
        self.a = a
 
    def get_a(self):
        return self.a
 
d = {
    True: MyClass('first'),
    False: MyClass('second')
}
 
check = False
 
for i in range(10):
    check = not check
    out = d[check].get_a()
    print(out)
    time.sleep(1)
m1r42
xam1816
вы путаете наследование с присвоением
Спасибо за ответ. Я правильно понимаю, что в моей конструкции c = x или c = y это всего лишь присвоение еще одного имени экземпляру класса. И обращаясь к нему по имени “c” по сути я имею дело с “x” или “y”. По крайней мере при работе программы это выглядит именно так.
В вашем же случае вы меняете переменную “a” в самом классе. А если у этого класса будет несколько экземпляров и у каждого будут свои значения переменной “a”?
m1r42
Собственно, что и требовалось доказать:
 class class1(object):
    def __init__(self):
        self.a = ""
x = class1()
x.a = "first"
print("Это экземпляр x - >",id(x))
y = class1()
y.a = "second"
print("Это экземпляр y - >",id(y))
check = False
c = x
for i in range(0,2):
    check = not check
    if check == True:
        c = x
        print("Это экземпляр x, но уже с именем c - >",id(c))
    if check == False:
        c = y
        print("Это экземпляр y, но уже с именем c - >",id(c))
Результат:
Это экземпляр x - > 50113264
Это экземпляр y - > 53866352
Это экземпляр x, но уже с именем c - > 50113264
Это экземпляр y, но уже с именем c - > 53866352


ZerG
m1r42
А если у этого класса будет несколько экземпляров и у каждого будут свои значения переменной “a”?
То следует прочесть 2 странички текста на тему Python наследование классов
В противном случае вы будете вспотыкаться еще сотни раз
https://www.bestprog.net/ru/2021/02/09/python-class-inheritance-rules-ru/
m1r42
ZerG
То следует прочесть 2 странички текста на тему Python наследование классов
В противном случае вы будете вспотыкаться еще сотни раз
https://www.bestprog.net/ru/2021/02/09/python-class-inheritance-rules-ru/
За это я и полюбил форум. Обязательно подтянусь в этом вопросе. Что вы скажете про мой пост выше про имена, я таки прав или нет? Если у объекта один id то это все тот же объект, но с другим именем? Может ведь такое быть?
ZerG
Я скажу что за
class class1() следует зажимать пальцы в тиски и проводить особо жестокие пытки
Так же скажу что вы пытаетесь интуитивно понять то - что нужно знать как отче наш.
Для чего нужно таки почитать книжку. В разделе про переменные и классы детально все рассказываеться

Так же для самообразования - попробуйте испольовать не запуск скрипта а любой дебаггер.
Вот в дебаггере как раз выполняя строку за строкой увидите как меняеться айди любого обьекта в зависимости от действия над оным.
Хорошие дебаггеры есть в пишарме и vscode
Но рекомендую прочесть М.Лутца - раздел классы от корки до корки.
Поверьте - это секономит вам кучу времени и в следующий раз взглянув на свой же вопрос
вы хлопните себя по лбу ладошкой и в слух произнесете что-то типа
Капец я лосяра… все ж написано и понятно как день!
py.user.next
m1r42
  
class class1(object):
    def __init__(self):
        self.a = ""
x = class1()
x.a = "first"
y = class1()
y.a = "second"
check = False
for i in range(0,10):
    check = not check
    if check == True:
        q = x.a
        print(q)
    if check == False:
        q = y.a
        print(q)
Собственно вопрос в том можно ли вместо объекта установить некий шаблон, а в начале цикла только менять имя x на y и наоборот?
Это твой изначальный код
  
class class1(object):
    def __init__(self):
        self.a = ""
 
x = class1()
x.a = "first"
 
y = class1()
y.a = "second"
 
check = False
for i in range(0,10):
    check = not check
    if check == True:
        q = x.a
        print(q)
    if check == False:
        q = y.a
        print(q)
Это код с “шаблоном”
  
class class1(object):
    def __init__(self):
        self.a = ""
 
x = class1()
x.a = "first"
 
y = class1()
y.a = "second"
 
check = False
for i in range(0,10):
    check = not check
    if check == True:
        q = x
    if check == False:
        q = y
    print(q.a)
Это вывод в консоли для кода с “шаблоном”
  
>>> class class1(object):
...     def __init__(self):
...         self.a = ""
... 
>>> x = class1()
>>> x.a = "first"
>>> 
>>> y = class1()
>>> y.a = "second"
>>> 
>>> check = False
>>> for i in range(0,10):
...     check = not check
...     if check == True:
...         q = x
...     if check == False:
...         q = y
...     print(q.a)
... 
first
second
first
second
first
second
first
second
first
second
>>>

m1r42
Хочу услышать мнение экспертов по этому вопросу. Типа, почему я не прав и почему так делать нельзя.
Имена в питоне не привязаны к объектам сначала и навсегда.
Например
  
>>> int(1)
1
>>> int = float
>>> int(1)
1.0
>>>
>>> int = 'abc'
>>> int(1)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'str' object is not callable
>>> print(int)
abc
>>>
Есть имя int и есть имя float. Эти имена привязаны к классам. Но в любой момент имя можно перевязать к другому объекту. Объектом может быть какой-то класс, а может быть какое-то число или какая-то строка. Поначалу имя int привязано к классу для создания целых чисел. Поначалу имя float привязано к классу для создания вещественных чисел. Но перевязывая имя int с класса для создания целых чисел к классу для создания вещественных чисел, мы через это имя можем создавать вещественные числа. А потом, перевязывая имя int с класса для создания вещественных чисел к объекту строка, мы через это имя можем получать эту строку.

m1r42
Хочу понять, возможно ли такое наследование и какими проблемами оно грозит в дальнейшем?
Это не наследование.
Пример наследования
  
>>> class MyInt(int):
...     def __init__(self, value):
...         self.root = value ** 0.5
... 
>>> number = MyInt(4)
>>> 
>>> number
4
>>> number.root
2.0
>>>
Мы пронаследовали класс MyInt от класса int и добавили в классе-наследнике MyInt к самому числу ещё и корень этого числа.
Наследование проводится для того, чтобы использовать то, что уже есть, чтобы это повторно всё не описывать. Поэтому в данном примере весь функционал класса int просто наследуется напрямую, а потом своё мы уже добавляем к унаследованному функционалу просто в виде описания. А дальше мы можем пронаследоваться от класса MyInt и использовать функционал int и функционал MyInt, чтобы в классе-наследнике всё это повторно не описывать.
  
>>> class MyInt(int):
...     def __init__(self, value):
...         self.root = value ** 0.5
... 
>>> class MyPrettyInt(MyInt):
...     def __str__(self):
...         return 'My value is {}, my root is {}.'.format(self.real, self.root)
... 
>>> number = MyPrettyInt(4)
>>> 
>>> print(number)
My value is 4, my root is 2.0.
>>>

m1r42
Люблю критику в стиле “ты ничего не понимаешь в ООП, надо тебе вернуться в процедурную парадигму программирования
Так что ты даже когда термин “наследование” используешь, ты не понимаешь, о чём говоришь, потому что просто ничего не знаешь, так как не читал никаких книг особо. Поэтому тебе и говорят, что тебе ООП не нужно на данном этапе, ты его не поймёшь ещё пока что, даже если там сто кодов напишешь с ним. ООП - слишком обширная и объемлющая тема; немногие опытные программисты понимают её даже (хоть и знают синтаксис записи), и из-за этого у них ООПшных программ нет (программ размером в 20000 и более строк), а они этого даже не замечают, просиживая за компом десятки лет и всем рассказывая, какие они крутые асинхронные программисты. Хочется только улыбаться и плакать, сочувствуя им. Так что начинай с процедурок, на них можно всё написать, что тебе нужно и будет нужно в ближайшие три года. Если не можешь написать на процедурках и якобы тебе нужно ООП для этого, то это значит, что ты процедурки просто плохо освоил. Раньше все игры писали на процедурках и всё работало прекрасно. Тот же тетрис возьми, змёйку, крестики-нолики, морской бой, шахматы, гонки формулы один, - это всё писалось на процедурках.
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB