У меня такая ситуация ...
class Outer(object):
def some_method(self):
# do something
class Inner(object):
def __init__(self):
self.Outer.some_method() # <-- this is the line in question
Как я могу получить доступ к Outer
методу Inner
класса из класса?
python
scope
nested
inner-classes
Т. Стоун
источник
источник
self.<original_parent_name>
и получить исходный класс, а не новый класс, от которого они являются подклассом . Я надеюсь, что люди, читающие это, смогут представить себе этот сложный сценарий и понять суть подобных вопросов.Ответы:
Методы вложенного класса не могут напрямую обращаться к атрибутам экземпляра внешнего класса.
Обратите внимание, что экземпляр внешнего класса не обязательно существует, даже если вы создали экземпляр внутреннего класса.
Фактически, часто не рекомендуется использовать вложенные классы, поскольку вложение не подразумевает каких-либо конкретных отношений между внутренним и внешним классами.
источник
Вы пытаетесь получить доступ к экземпляру класса Outer из экземпляра внутреннего класса. Поэтому просто используйте фабричный метод для создания внутреннего экземпляра и передачи ему внешнего экземпляра.
источник
может быть, я злюсь, но это действительно кажется очень простым - дело в том, чтобы сделать ваш внутренний класс методом внешнего класса ...
Плюс ... "self" используется только по соглашению, поэтому вы можете сделать это:
Могут возразить, что вы не можете создать этот внутренний класс извне внешнего класса ... но это неверно:
потом, где-то далеко:
даже немного вытолкните лодку и расширите этот внутренний класс (NB, чтобы заставить super () работать, вам нужно изменить подпись класса mooble на "class mooble (object)"
потом
mrh1997 поднял интересный вопрос о необычном наследовании внутренних классов, доставляемых с использованием этой техники. Но кажется, что решение довольно простое:
источник
Вы хотите использовать наследование, а не такие классы вложенности? То, что вы делаете, не имеет большого смысла в Python.
Вы можете получить доступ к
Outer
some_method, просто сославшись наOuter.some_method
методы внутреннего класса, но он не будет работать так, как вы ожидаете. Например, если вы попробуете это:... вы получите TypeError при инициализации
Inner
объекта, потому чтоOuter.some_method
ожидает получитьOuter
экземпляр в качестве своего первого аргумента. (В приведенном выше примере вы в основном пытаетесь вызватьsome_method
метод классаOuter
.)источник
Вы можете легко получить доступ к внешнему классу с помощью метакласса: после создания внешнего класса проверьте его атрибут dict для любых классов (или примените любую нужную вам логику - мой просто тривиальный пример) и установите соответствующие значения:
Используя этот подход, вы можете легко связать два класса друг с другом и ссылаться на них.
источник
Я создал код Python для использования внешнего класса из его внутреннего класса , основываясь на хорошей идее из другого ответа на этот вопрос. Я думаю, это коротко, просто и понятно.
Основной код, «готовый к производству» (без комментариев и т.п.). Не забудьте заменить все значения в угловых скобках (например
<x>
) на желаемое.Объяснение того, как работает этот метод (основные шаги):
Создайте функцию с именем, которая
_subclass_container
будет действовать как оболочка для доступа к переменнойself
, ссылка на класс более высокого уровня (из кода, выполняемого внутри функции).Создайте переменную с именем,
_parent_class
которая является ссылкой на переменнуюself
этой функции, к которой подклассы_subclass_container
могут получить доступ (избегая конфликтов имен с другимиself
переменными в подклассах).Верните подкласс / подклассы как словарь / список, чтобы код, вызывающий
_subclass_container
функцию, мог получить доступ к подклассам внутри.В
__init__
функции внутри класса более высокого уровня (или где-либо еще) получите возвращенные подклассы из функции_subclass_container
в переменнуюsubclasses
.Назначьте подклассы, хранящиеся в
subclasses
переменной, атрибутам класса более высокого уровня.Несколько советов по упрощению сценариев:
Упрощение копирования кода для присвоения подклассов классу более высокого уровня и его использования в классах, производных от класса более высокого уровня,
__init__
функция которых изменилась:Вставьте перед строкой 12 в основной код:
Затем вставьте в эту функцию строки 5-6 (основного кода) и замените строки 4-7 следующим кодом:
Обеспечение возможности присвоения подкласса классу более высокого уровня, когда существует много / неизвестное количество подклассов.
Замените строку 6 следующим кодом:
Пример сценария того, где было бы полезно это решение и где невозможно получить имя класса более высокого уровня:
Создается класс с именем «a» (
class a:
). У него есть подклассы, которым необходим доступ к нему (родительский). Один подкласс называется «x1». В этом подклассе выполняется кодa.run_func()
.Затем создается другой класс с именем «b», производный от класса «a» (
class b(a):
). После этого выполняется некоторый кодb.x1()
(вызывающий подфункцию «x1» из b, производного подкласса). Эта функция запускаетсяa.run_func()
, вызывая функцию «run_func» класса «a», а не функцию «run_func» ее родительского элемента «b» (как и должно быть), поскольку функция, которая была определена в классе «a», настроена для ссылки функции класса «а», поскольку она была ее родителем.Это вызовет проблемы (например, если функция
a.run_func
была удалена), и единственным решением без переписывания кода в классеa.x1
было бы переопределение подклассаx1
с обновленным кодом для всех классов, производных от класса «a», что, очевидно, было бы сложно и не стоит Это.источник
Я нашел это .
Изменено, чтобы удовлетворить ваш вопрос:
Я уверен, что можно как-нибудь написать декоратор для этого или чего-то такого
связанные: Какова цель внутренних классов Python?
источник
Другая возможность:
источник
Расширяя убедительное мышление @ tsnorri, что внешний метод может быть статическим :
Теперь рассматриваемая линия должна работать к моменту фактического вызова.
Последняя строка в приведенном выше коде дает внутреннему классу статический метод, который является клоном внешнего статического метода.
При этом используются две возможности Python: функции являются объектами , а область видимости - текстовой .
... или текущий класс в нашем случае. Таким образом, объекты, «локальные» по отношению к определению внешнего класса (
Inner
иsome_static_method
), могут упоминаться непосредственно в этом определении.источник
Несколько лет опоздали на вечеринку .... но чтобы расширить
@mike rodent
замечательный ответ, я привел свой собственный пример ниже, который показывает, насколько гибким является его решение и почему оно должно быть (или должно было быть) приемлемым ответ.Python 3.7
Вывод:
Опять же, прекрасный ответ, спасибо, Майк!
источник
Это слишком просто:
Вход:
Вывод
класс A func1
класс B func1
источник
func1
. И, что не менее забавно, вы создаетеA
внутри конструктораB
, который абсолютно НЕ являетсяA
объектом внешнего класса этого конкретногоB
.