Наследование и создание экземпляров классов - путаница между внутренними вызовами методов __init __ () и __new __ () - PullRequest
0 голосов
/ 19 февраля 2020

Это дополнительный вопрос к проблеме Я ранее отправил , который был частично решен с ответом, который я получил.

  • Сценарий состоит в том, что у меня есть 1 класс, определенный во время выполнения, который наследуется от класса, определенного на основе типа: MasterData или Transaction, который, в свою очередь, наследует от BusinessDocument ,
  • Класс BusinessDocument должен наследоваться от класса Thing , который доступен через внешний модуль.

Следующий код был реализован для создания всех классов в цепочке:

from owlready2 import *

with onto:
    class BusinessDocument(Thing):
        @staticmethod
        def get_class(doc_type):
            switch = {
                'MasterData': MasterData,
                'Transactional': Transactional
            }
            cls = switch.get(doc_type, lambda: "Invalid Noun Type")
            return cls

        def __init__(self, doc_id, location, doc_type, color, size):
            self.doc_id = doc_id
            self.location = location
            self.doc_type = doc_type
            self.color = color
            self.size = size

        @property
        def get_location(self):
            return self.location

        @property
        def get_doc_id(self):
            return self.doc_id

with onto:
    class MasterData(BusinessDocument):
        def __init__(self, doc_id, location, color, size):
            BusinessDocument.__init__(self, doc_id, location, color, size, 'MasterData')

with onto:    
    class Transactional(BusinessDocument):
        def __init__(self, doc_id, location, color, size):
            BusinessDocument.__init__(self, doc_id, location, color, size, 'Transactional')


with onto:
    class NounClass():
        @staticmethod
        def get_class(doc_name, doc_type):
            return type(doc_name, (BusinessDocument.get_class(doc_type), 
                               BusinessDocument, ),dict.fromkeys(['doc_id', 'location', 'color', 'size',])) 

Во время выполнения, когда я получаю doc_name и получаю новый класс, но когда я пытаюсь создать экземпляр.

invoice_cls = NounClass.get_class('Invoice', 'Transactional')
my_invoice = invoice_cls('IN-1234', 'New York', 'blue', 'big')

Вызовы типа () и методы mro () для invoice_cls дают мне следующую информацию:

DEBUG:app.__main__:Type of from_noun is [(bod_ontology.Invoice, bod_ontology.MasterData, bod_ontology.BusinessDocument, owl.Thing, <class 'object'>)]
DEBUG:app.__main__:Class type is [<class 'owlready2.entity.ThingClass'>]

Но затем я получаю исключение, связанное с методом __new__():

DEBUG:app.__main__:Type of from_noun is [(bod_ontology.BillFromPartyMaster, bod_ontology.MasterData, bod_ontology.BusinessObjectDocument, owl.Thing, <class 'object'>)]
DEBUG:app.__main__:Class type is [<class 'owlready2.entity.ThingClass'>]
  File "/Users/cracoras/PycharmProjects/bod2owl/app/convert_data.py", line 167, in parse_xml
    my_invoice = invoice_cls('IN-1234', 'New York', 'blue', 'big')
--- Logging error ---
Traceback (most recent call last):
  File "/Users/cracoras/PycharmProjects/bod2owl/app/convert_data.py", line 167, in parse_xml
    my_invoice = invoice_cls('IN-1234', 'New York', 'blue', 'big')
TypeError: __new__() takes from 1 to 3 positional arguments but 5 were given

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/Users/cracoras/.pyenv/versions/3.8.1/lib/python3.8/logging/__init__.py", line 1081, in emit
    msg = self.format(record)
  File "/Users/cracoras/.pyenv/versions/3.8.1/lib/python3.8/logging/__init__.py", line 925, in format
    return fmt.format(record)
  File "/Users/cracoras/.pyenv/versions/3.8.1/lib/python3.8/logging/__init__.py", line 664, in format
    record.message = record.getMessage()
  File "/Users/cracoras/.pyenv/versions/3.8.1/lib/python3.8/logging/__init__.py", line 369, in getMessage
    msg = msg % self.args
TypeError: must be real number, not TypeError
Call stack:
  File "/Applications/PyCharm.app/Contents/helpers/pydev/pydevd.py", line 1758, in <module>
    main()
  File "/Applications/PyCharm.app/Contents/helpers/pydev/pydevd.py", line 1752, in main
    globals = debugger.run(setup['file'], None, None, is_module)
  File "/Applications/PyCharm.app/Contents/helpers/pydev/pydevd.py", line 1147, in run
    pydev_imports.execfile(file, globals, locals)  # execute the script
  File "/Applications/PyCharm.app/Contents/helpers/pydev/_pydev_imps/_pydev_execfile.py", line 18, in execfile
    exec(compile(contents+"\n", file, 'exec'), glob, loc)
  File "/Users/cracoras/PycharmProjects/bod2owl/app/convert_data.py", line 520, in <module>
    exit(main())
  File "/Users/cracoras/PycharmProjects/bod2owl/app/convert_data.py", line 515, in main
    query_database()
  File "/Users/cracoras/PycharmProjects/bod2owl/app/convert_data.py", line 103, in query_database
    csv_record = parse_xml(bod_type, date_time, from_lid, tenant, xml_string)
  File "/Users/cracoras/PycharmProjects/bod2owl/app/convert_data.py", line 174, in parse_xml
    log.debug("Got an error [%e]", e)
Arguments: (TypeError('__new__() takes from 1 to 3 positional arguments but 5 were given'),)

Затем, если я попытаюсь сделать вызов экземпляра без аргументов, я получу другое исключение, связанное с методом __init__(), и вот полное:

DEBUG:app.__main__:Type of from_noun is [(bod_ontology.BillFromPartyMaster, bod_ontology.MasterData, bod_ontology.BusinessObjectDocument, owl.Thing, <class 'object'>)]
DEBUG:app.__main__:Class type is [<class 'owlready2.entity.ThingClass'>]
  File "/Users/cracoras/PycharmProjects/bod2owl/app/convert_data.py", line 167, in parse_xml
    my_invoice = invoice_cls()
--- Logging error ---
Traceback (most recent call last):
  File "/Users/cracoras/PycharmProjects/bod2owl/app/convert_data.py", line 167, in parse_xml
    my_obj = MyCls()
TypeError: __init__() missing 4 required positional arguments: 'doc_id', 'location', 'color', and 'size'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/Users/cracoras/.pyenv/versions/3.8.1/lib/python3.8/logging/__init__.py", line 1081, in emit
    msg = self.format(record)
  File "/Users/cracoras/.pyenv/versions/3.8.1/lib/python3.8/logging/__init__.py", line 925, in format
    return fmt.format(record)
  File "/Users/cracoras/.pyenv/versions/3.8.1/lib/python3.8/logging/__init__.py", line 664, in format
    record.message = record.getMessage()
  File "/Users/cracoras/.pyenv/versions/3.8.1/lib/python3.8/logging/__init__.py", line 369, in getMessage
    msg = msg % self.args
TypeError: must be real number, not TypeError
Call stack:
  File "/Applications/PyCharm.app/Contents/helpers/pydev/pydevd.py", line 1758, in <module>
    main()
  File "/Applications/PyCharm.app/Contents/helpers/pydev/pydevd.py", line 1752, in main
    globals = debugger.run(setup['file'], None, None, is_module)
  File "/Applications/PyCharm.app/Contents/helpers/pydev/pydevd.py", line 1147, in run
    pydev_imports.execfile(file, globals, locals)  # execute the script
  File "/Applications/PyCharm.app/Contents/helpers/pydev/_pydev_imps/_pydev_execfile.py", line 18, in execfile
    exec(compile(contents+"\n", file, 'exec'), glob, loc)
  File "/Users/cracoras/PycharmProjects/bod2owl/app/convert_data.py", line 520, in <module>
    exit(main())
  File "/Users/cracoras/PycharmProjects/bod2owl/app/convert_data.py", line 515, in main
    query_database()
  File "/Users/cracoras/PycharmProjects/bod2owl/app/convert_data.py", line 103, in query_database
    csv_record = parse_xml(bod_type, date_time, from_lid, tenant, xml_string)
  File "/Users/cracoras/PycharmProjects/bod2owl/app/convert_data.py", line 174, in parse_xml
    log.debug("Got an error [%e]", e)
Arguments: (TypeError("__init__() missing 4 required positional arguments: 'doc_id', 'location', 'color', and 'size'"),)

Это происходит только тогда, когда я наследую из класса «Вещи». Если я удалю наследство, код будет работать нормально. Похоже, я испортил последовательность создания экземпляров в иерархии классов.

1 Ответ

0 голосов
/ 19 февраля 2020

Кажется, что проблема вызвана классом Thing, как я и подозревал, @quamrana.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...