Это вопрос об общем принципе самоанализа. Когда вы находитесь внутри метода, как мы можем дать возможность определить, в каком классе мы сейчас находимся?
Мы хотим что-то вроде следующего:
class FigNewton:
def baz(self):
current_class = MAGIC()
Что бы MAGIC
быть? Следующее недопустимо, так как мы работаем в среде, где глобальные вызовы не доверяют. Глобальные данные во время определения являются доверенными, но не глобальные во время вызова метода.
class FigNewton:
def baz(self):
current_class = FigNewton
Почему глобальные переменные не являются доверенными во время вызова? Из-за следующих махинаций:
class FigNewton:
def baz(self):
current_class = FigNewton
print("banana")
print("current_class ==", current_class.__name__)
import itertools
import string
print = lambda *args, print=print:\
print(
sum(
map(
lambda stryng:\
int(''.join(
itertools.takewhile(
lambda ch: ch in string.ascii_lowercase
,
stryng
)
), base=36)
,
map(str, args)
)
, )
)
print("apple")
obj = FigNewton()
FigNewton = "apple"
obj.baz()
Вывод:
17995730
683010982
27999997387
Вместо ожидаемого:
apple
banana
current_class == FigNewton
Ниже приведен код, демонстрирующий проблему:
class K0:
print=print
type=type
def foo(self, *args):
self.print(40 * "--")
self.print('args == ', args)
self.print("K0 version of foo is executing.")
self.print("Are all references to class K0 lost?")
self.print("Well, global label `K0` is ", self.type(K0).__qualname__, K0)
# K0.__getattribute__(self, "whatever") ## ERROR!!!
tsqn = self.type(self).__qualname__
self.print(
"type(self) is ", tsqn,
". Is that K0? ", ("yes" if tsqn == "K0" else "no"),
sep=""
)
self.print(40 * "--")
##########################################################
def test(seed_class):
Ks = [seed_class]
for idx in (1, 2, 3):
K = type("K{}".format(idx), (Ks[-1],), dict())
Ks.append(K)
class K4(Ks[-1]):
def foo(self):
print("K10 version of foo is executing")
print("type(self) is ", type(self))
# Begin messing up global namespace
global K0
K0 = 0
# End messing up global namespace
Ks.pop(0)
for K in Ks:
obj = K()
obj.foo(1, 2, 3)
return None
##########################################################
test(K0)
Вывод:
--------------------------------------------------------------------------------
args == (1, 2, 3)
K0 version of foo is executing.
Are all references to class K0 lost?
Well, global label `K0` is int 0
type(self) is K1. Is that K0? no
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
args == (1, 2, 3)
K0 version of foo is executing.
Are all references to class K0 lost?
Well, global label `K0` is int 0
type(self) is K2. Is that K0? no
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
args == (1, 2, 3)
K0 version of foo is executing.
Are all references to class K0 lost?
Well, global label `K0` is int 0
type(self) is K3. Is that K0? no
--------------------------------------------------------------------------------