我有一个自定义类,它继承了Python的内置datetime.date
类:
# types.py
from datetime import date
class Date(date):
def __new__(cls, *args, isExceptional: bool = None, **kwargs):
if len(args) == 1 and isinstance(args[0], date):
self = super().__new__(
cls, args[0].year, args[0].month, args[0].day, **kwargs)
else:
self = super().__new__(cls, *args, **kwargs)
if isExceptional is not None:
self._isOff = True if self.isoweekday() in (6, 7) else False
if isExceptional:
self._isOff = not self._isOff
else:
self._isOff = None
return self
@property
def isOff(self):
return self._isOff
@isOff.setter
def isOff(self, value: bool):
if self._isOff is not None:
raise AttributeError(
"'isOff' can be set only when it is currently undefined, i.e. None"
)
else:
self._isOff = value
总之,Date
类似于内置的date
,具有附加的_isOff
属性及其访问器。它的构造函数接受标准的date
对象或原始date
构造函数可以接受的任何对象作为参数,同时只接受一个额外的关键字来操作_isOff
值。你知道吗
这门课基本上是有效的,就像
test = Date(2019, 9, 15)
print(test.isoformat(), "; isOff:", test.isOff)
test = Date(2019, 9, 15, isExceptional=False)
print(test.isoformat(), "; isOff:", test.isOff)
test = Date(2019, 9, 15, isExceptional=True)
print(test.isoformat(), "; isOff:", test.isOff)
给了我:
2019-09-15 ; isOff: None
2019-09-15 ; isOff: True
2019-09-15 ; isOff: False
另一方面,我有一张桌子:
CREATE TABLE `date` (
`date` DATE NOT NULL,
`isOff` BIT(1) NOT NULL DEFAULT b'0',
PRIMARY KEY (`date`)
)
COLLATE='utf8mb4_general_ci'
ENGINE=InnoDB
;
我想在他们之间做一个炼金术映射。我搞不懂“声明式”的方法,所以我尝试了经典的映射,比如:
# orm.py
import sqlalchemy as ORM
date = ORM.Table(
'date',
ORM.MetaData(),
ORM.Column('date', ORM.Date, primary_key=True),
ORM.Column('isOff', ORM.Boolean)
)
# types.py, after the Date class definition
from . import orm
from sqlalchemy.orm import mapper
mapper(Date, orm.date)
在上面,test = Date(2019, 9, 15)
给我
Traceback (most recent call last):
File "c:\users\user\appdata\local\programs\python\python37-32\Lib\runpy.py", line 193, in _run_module_as_main
"__main__", mod_spec)
File "c:\users\user\appdata\local\programs\python\python37-32\Lib\runpy.py", line 85, in _run_code
exec(code, run_globals)
File "D:\data\work\newsys\newsys\types.py", line 39, in <module>
test = Date(2019, 9, 15)
TypeError: __init__() takes 1 positional argument but 4 were given
我猜错误消息中提到的__init__()
来自SQLAlchemy的映射机制,因为在我的类和标准的date
类中都没有定义__init__()
。除此之外,我不知道发生了什么。。。“1位置参数”应该是什么?作为这4个参数提供了什么?你知道吗
如何映射它们,只需对Date类进行最小的修改?你知道吗
请注意,在
Date
abdorm.date
上调用mapper
将使用SQLAlchemy的内部使用的元类更改Date
类。如果您同时覆盖__new__
,您将陷入一个冲突的情况。你知道吗SQLAlchemy似乎试图为您提供一个默认的
__init__
实现。我不知道为什么会这样,但是如果同时覆盖__init__
,就没有问题了。因为你不需要特殊的处理,所以把下面的内容放到你的课堂上是可以的。你知道吗一个快速测试表明,它不会崩溃之后。你知道吗
相关问题 更多 >
编程相关推荐