Во время оформления one_way()
представляет собой простую функцию , а не метод - она становится методом только при поиске на экземпляре B
. Итак, вам нужно явно предоставить экземпляр B
при вызове его из A().run()
(тот факт, что в вашем коде есть глобальный экземпляр b
, не имеет значения - объект функции, хранящийся в a.rmap
, абсолютно ничего не знает об этом, и даже не о B
классе FWIW.
Короче говоря, ваш текущий дизайн не может работать как есть. Если вы когда-нибудь намереваетесь декорировать методы (ну, функции) из одного класса и вызывать их в одном экземпляре этого класса, вы можете передать экземпляр этого класса в a.run()
ie:
class A():
# ...
def run(self, obj):
data = [1,2,3]
for k in self.rmap.keys():
self.rmap[k](obj, data)
b = B()
a.run(b)
, но это будет очень ограниченное использование.
Или Вы можете просто использовать декоратор, чтобы «пометить» функции, которые будут использоваться для маршрутизации (вместе с эффективным маршрутом), добавить немного register()
methdo к A
и явно передать B
или любой другой экземпляр этого метода ie
def route(r):
def decorator(f):
f._A_route = r
return f
return decorator
class A (object):
def __init__(self):
self.rmap = {}
def register(self, *objects):
for obj in objects:
self._register(obj)
def _register(self, obj):
for name in dir(obj):
if name.startswith("_"):
continue
attr = getattr(obj, name)
if callable(attr) and hasattr(attr, "_A_route"):
self.rmap[attr._A_route] = attr
def run(self):
data = [1,2,3]
for k in self.rmap.keys():
self.rmap[k](data)
class B (object):
def __init__(self):
pass
@route('/one/way')
def one_way (self, data):
print('A WAY:{}'.format(self))
if __name__ == "__main__":
a = A()
b = B()
a.register(b)
a.run()
Теперь могут быть лучшие решения для вашего конкретного варианта использования, но невозможно сказать, не зная всего контекста и т. Д. c. * 1 024 *