[英]isinstance not working for Decimal in AppEngine
I have an instance of decimal.Decimal
which comes from an SQLAlchemy query. 我有一个
decimal.Decimal
实例,它来自SQLAlchemy查询。 As I need to serialize the object, I have created a JSON serializer to deal with the Decimal
: 因为我需要序列化对象,所以我创建了一个JSON序列化程序来处理
Decimal
:
import decimal
class AlchemyEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, decimal.Decimal):
return str(obj)
return json.JSONEncoder.default(self, obj)
The unfortunate thing is that the isinstance(obj, decimal.Decimal)
does not return a True
for the instance, even though (using pdb in the default
method above): 不幸的是,即使(在上面的
default
方法中使用pdb isinstance(obj, decimal.Decimal)
, isinstance(obj, decimal.Decimal)
也不会为实例返回True
:
obj.__class__ # => <class 'decimal.Decimal'>
blah = decimal.Decimal()
blah.__class__ # => <class 'decimal.Decimal'>
isinstance(obj, decimal.Decimal) # => False
isinstance(blah, decimal.Decimal) # => True
isinstance(obj, obj.__class__) # => True
I did check that the module both instances refer to is the same module: 我确实检查了两个实例引用的模块是同一个模块:
import inspect
inspect.getfile(obj.__class__) # => '/usr/local/Cellar/python/2.7.11/Frameworks/Python.framework/Versions/2.7/lib/python2.7/decimal.pyc'
inspect.getfile(blah.__class__) # => '/usr/local/Cellar/python/2.7.11/Frameworks/Python.framework/Versions/2.7/lib/python2.7/decimal.pyc'
I would really love to understand why this is not working! 我真的很想知道为什么这不起作用!
EDIT 编辑
It turns out that the issue only occurs when running under AppEngine's dev_appserver.py
environment. 事实证明,只有在AppEngine的
dev_appserver.py
环境下运行时才会出现此问题。 A simple: 一个简单的:
isinstance(db.session.execute('SELECT amount FROM model LIMIT 1').fetchone()[0], decimal.Decimal)
returns False
when making a request via the AppEngine dev_appserver and True
when run from the console. 通过AppEngine dev_appserver发出请求时返回
False
,从控制台运行时返回True
。
Ran into this today, and came across an old mailing list post that discussed this. 今天进入这个,并遇到了一个旧的邮件列表帖子 ,讨论了这一点。
Turns out this question has also been addressed on stackoverflow previously as well. 事实证明,此问题也已在stackoverflow上得到解决。 Pasting the answer here for ease of access / reduced stackoverflow server load:
在此处粘贴答案以便于访问/减少stackoverflow服务器负载:
It appears that the decimal.Decimal class is patched somewhere in the Google App Engine SDK (or the module is reloaded), and this is done between the MySQL conversion library importing decimal and you importing the same. 似乎decimal.Decimal类在Google App Engine SDK中的某个位置打了补丁(或者重新加载了模块),这是在MySQL转换库导入小数和导入小数之间完成的。
Luckily, we can work around this by updating MySQL conversion table: 幸运的是,我们可以通过更新MySQL转换表来解决这个问题:
from MySQLdb.constants import FIELD_TYPE
from MySQLdb.converters import conversions
import decimal
conversions[FIELD_TYPE.DECIMAL] = conversions[FIELD_TYPE.NEWDECIMAL] = decimal.Decimal
That's it; 而已; the above code resets the MySQL class and your JSON encoder type check succeeds.
上面的代码重置MySQL类,你的JSON编码器类型检查成功。
The alternative would be for you to look for the class MySQLdb is using: 替代方法是让您查找MySQLdb正在使用的类:
class DecimalEncoder(json.JSONEncoder):
def default(self, o):
if isinstance(o, MySQLdb.converters.conversions[MySQLdb.constants.FIELD_TYPE.DECIMAL]):
return float(o)
return super(DecimalEncoder, self).default(o)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.