这是我之前发布的问题的后续问题,该问题已通过我收到的答案部分解决。
- 场景是我有 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')
调用 invoice_cls 的 type() 和mro () 方法可以得到以下信息:
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'"),)
这只发生在我从“事物”类继承时。如果我删除继承,代码运行得很好。看起来我弄乱了类层次结构中的实例化序列。