Ответ 1
В общем случае мы не хотим, чтобы func
имел доступ к вызывающему экземпляру A
, потому что это прерывает encapsulation. Внутри b.func
вы должны иметь доступ к любым переданным args и kwargs, состоянию/атрибутам экземпляра b
(через self
здесь) и любым глобальным переменным.
Если вы хотите узнать о вызывающем объекте, допустимыми способами являются:
- Передайте вызывающий объект в качестве аргумента функции
- Явно добавить дескриптор вызывающего на экземпляр
b
, прежде чем использоватьfunc
, а затем получить доступ к этому дескриптору черезself
.
Однако с учетом этого отказа от ответственности все же стоит знать, что возможности интроспекции python достаточно мощны для доступа к модулю вызывающего модуля в некоторых случаях. В реализации CPython вы можете получить доступ к экземпляру вызывающего A
без изменения интерфейсов:
class A():
def go(self):
b=B()
b.func()
class B():
def func(self):
import inspect
print inspect.currentframe().f_back.f_locals['self']
if __name__ == '__main__':
a = A()
a.go()
Вывод:
<__main__.A instance at 0x15bd9e0>
Это может быть полезной уловкой, чтобы иногда разбираться в отладке кода. Но было бы разумным конструктивным решением когда-либо обращаться к фреймам стека, как это в случае, когда b.func
действительно необходимо использовать A
по любой причине.