#python #class #oop #inheritance
#питон #класс #ООП #наследование
Вопрос:
Я пытаюсь создать параллельную структуру классов в двух отдельных модулях, где методы классов в одном модуле, например source.py
, регистрируются в модулях с одинаковыми именами receiving.py
через наследование.
Моя проблема заключается в том, что если унаследованный метод in receiving.py
вызывает другой класс в модуле , он будет указывать на класс в source.py
, а не в receiving.py
. Я понимаю, что это ожидается, но как я могу изменить, на какой класс указывает метод во время или после сопоставления, чтобы метод в receiving.py
классе вызывал класс из receiving.py
.
Вот схема, которая поможет проиллюстрировать проблему. схематический
Минимально достаточный пример:
source.py
class Foo: origin = 'src' @classmethod def get_origin(cls): return cls.origin @classmethod def get_origin_bar(cls): return Bar.origin class Bar: origin = 'src'
receiving.py
class Tag: pass class Foo(Tag): origin = 'rec' class Bar(Tag): origin = 'rec'
def register_bases(base, module): """ Recursive function that adds __bases__ from DataJoint Tables in base to matching classes in module. :param base (module): source module with classes to. :param module (module): mapping between classes and methods """ for name in dir(base): base_cls = getattr(base, name) module_cls = getattr(module, name) if hasattr(module, name) else None if module_cls and inspect.isclass(module_cls) and issubclass(module_cls, receiving.Tag): assert base_cls not in module_cls.__bases__, f'Class "{name}" of base already in __base__ of module.' module_cls.__bases__ = (base_cls, *module_cls.__bases__) register_bases(base_cls, module_cls)
import inspect import source, receiving # Before registering bases receiving.Foo.get_origin() -gt; AttributeError: type object 'Foo' has no attribute 'get_origin' receiving.Foo.get_origin_bar() -gt; AttributeError: type object 'Foo' has no attribute 'get_origin_bar'
# register bases register_bases(source, receiving)
# after registering bases receiving.Foo.get_origin() -gt; 'rec' receiving.Foo.get_origin_bar() -gt; 'src'
Что мне нужно , так это чтобы в последней строке было указано 'rec'
, что метод get_origin_bar
вызывается receiving.Bar.origin
вместо source.Bar.origin
.
Комментарии:
1. Почему вы не можете просто связать эти классы по наследованию, тем самым избежав проблемы, которую вы создали для себя, пытаясь создать параллели? В принципе, это звучит как проблема X-Y — пожалуйста, объясните, в чем заключается реальная проблема, которую вы пытаетесь решить?
2. привет, спасибо, что нашли время. не уверен, что понимаю предложенное вами решение. Вы предполагаете, что классы в
receiving.py
должны наследовать от своих исходных классов путем импортаsource.py
в модуль? Или вы спрашиваете, почему вообще существует два модуля? Проблема, которую я пытаюсь решить, заключается в том, что один модуль существует в Docker env, а другой модуль существует в API. Я пытаюсь разделить модули так, чтобы все, что может функционировать вне среды docker, могло существовать в API, но классы docker также могут наследовать эти методы.3. Чтобы связать его с примером.
source.py
будет модулем в API иreceiving.py
будет модулем в Docker env.4. Боюсь, ваше объяснение не имеет никакого смысла, и диаграмма тоже не имеет смысла — как может Foo наследовать от Foo или Bar наследовать от Bar?
5.
receiving.Foo
наследует отsource.Foo
иreceiving.Bar
наследует отsource.Bar