LINUX.ORG.RU

[Python][Вложенные классы] Доступ к полю внешнего класса из внутреннего

 


0

1

При написании кода появилась такая проблема, есть код следующего вида:

class OuterClass:
    __init__(self):
        self.var = 'somevar' # или просто var = 'somevar'
    class InnerClass:
        # некоторый код которому нужна var
        pass
Пока что решил проблему самым ужасным способом, global var. Какие есть более адекватные варианты, на SO нашел вариант когда вложенному классу передается объект внешнего, но такая реализация в моем случае не возможна к сожалению. :(



Последнее исправление: voronin (всего исправлений: 2)

Я правильно понимаю, что ты хочешь иметь доступ к полю несуществующего объекта?

Miguel ★★★★★
()

Не путать поля класса и поля объекта.

schizoid ★★★
()

Афтар, иди учить основы ООП.

на SO нашел вариант когда вложенному классу передается объект внешнего

Правильный, годный вариант.

но такая реализация в моем случае не возможна к сожалению

Мои соболезнования, но без наличия объекта ты не сможешь получить доступ к его полям, что какбэ очевидно.

NightmareZz
()
Ответ на: комментарий от voronin

Мм так а как? Просто я передаю классы, а не объекты, методу одной библиотеки.

Если объектов не существует, то к чему ты доступ собрался получать?

NightmareZz
()

# ~$ cat pyclass.py 

class Foo(object):

    def __init__(self):

        variable = "HALO!"

        self.variable = "GUDBIE!"

        that = self

        class Bar(object):

            def __init__(self):

                print variable

                print that.variable

        Bar()

Foo()

# ~$ python2.6 pyclass.py 
# HALO!
# GUDBIE!

trashymichael ★★★
()
Ответ на: комментарий от trashymichael

Тебя не смущает, что ты неявно передал внутреннему объекту ссылку на внешний? Аффтар говорил, что его это не устраивает.

NightmareZz
()
Ответ на: комментарий от NightmareZz

Объекты существуют, но создаются они кодом библиотеки. На Java то что нужно реализуемо так:

class OuterClass() {
   public OuterClass(){}
   private int outerField;
   class InnerClass {
      int getOuterField() {
         return OuterClass.this.outerField;
      }
   };
};

voronin
() автор топика
Ответ на: комментарий от voronin

На Java то что нужно реализуемо так:

Эээ... и ссылку на что возвращает выражение OuterClass.this, если не создано ни одного объекта класса OuterClass или, если создано несколько объектов?

NightmareZz
()
Ответ на: комментарий от NightmareZz

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

trashymichael ★★★
()
Ответ на: комментарий от NightmareZz

если бы в Bar передавалась ссылка на Foo::self, какой бы смысл тогда был делать его вложенным? а то что якобы «на Жава реализуемо так» вообще бред

trashymichael ★★★
()
Ответ на: комментарий от voronin

Так если InnerClass создан, создан и OuterClass же.

не путай классы и объекты. если даже InnerClass создан, как узнать какой именно объект OuterClass'а его создал? ты просто запутался и хочешь странного, давай ка ты нам всю задачу опишешь..

trashymichael ★★★
()
Ответ на: комментарий от voronin

На Java то что нужно реализуемо так:

А теперь говори, зачем тебе это нужно в питоне.

baverman ★★★
()

А пусть var будет полем объекта класса а не экземпляра класса, и будет все щастье...

AIv ★★★★★
()
Ответ на: комментарий от voronin

Так если InnerClass создан, создан и OuterClass же.

Нет, конечно.

Miguel ★★★★★
()
Ответ на: комментарий от trashymichael

если бы в Bar передавалась ссылка на Foo::self, какой бы смысл тогда был делать его вложенным?

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

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

NightmareZz
()
class OuterClass:
    
    def __init__(self):
        self.var = 'somevar' # или просто var = 'somevar'
    
    class InnerClass:
        # некоторый код которому нужна var
        pass

Ты не понимаешь почему хочешь странного, потому что не понимаешь как выполняется этот код. Как создается класс? Считывается его определение, оттуда выдергивается его его имя, базовые классы, и, если есть, метакласс. Потом выполняется тело класса (тело класса - это код, расположенный на один уровень отступа правее объявления класса, то есть оператора «class ...») в отдельном локальном неймспейсе класса (по сути это прообраз будущего __dict__ класса), а затем вся эта солянка (имя класса, базовые классы + полученный неймспейс) передается в метакласс, который должен вернуть готовый класс. Напоследок в неймспейсе, в котором расположено объявление класса, создается переменная с именем класса и туда помещается ссылка на этот объект(класс). Так вот метод __init__ инициализирует экземпляры уже _готового_ класса. А класс InnerClass создается в момент создания класса OuterClass, когда ещё и класса нет, а тем более его экземпляров. То есть вложенные классы создаются раньше классов, в которые вложены. Походу ты перевел код на Java на Python один в один, не учитывая специфики последнего.

Virtuos86 ★★★★★
()
Ответ на: комментарий от Virtuos86

Походу ты перевел код на Java на Python один в один, не учитывая специфики последнего.

Жабовский код тоже не заработает.

Miguel ★★★★★
()

Вобщем то да, отоспался и пересмотрел немного код, в итоге удалось переписать проще и наверное более правильно. Всем спасибо, действительно видимо пока что не до конца понимаю ООП.

voronin
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.