Tôi gặp sự cố khi mã hóa thành JSON bằng Python, cụ thể là các giá trị thập phân. Thập phân. Tôi đang sử dụng nó để xuất JSON cho ứng dụng Google App Engine.
Để tránh mặc định trong Python json
Mô-đun cho tôi biết rằng nó không thể xử lý các ngoại lệ cho các đối tượng thập phân. Thập phân, tôi đã sử dụng lớp con bộ mã hóa này:
lớp DecimalEncoding(json.JSONEncode):
mặc định mặc định (tự, o):
nếu isinstance(o, thập phân. Thập phân):
trả về float(o)
trả về super(DecimalEncode, self).default(o)
Trên các ứng dụng khác, tính năng này không hoạt động. Trong trường hợp này, nó không. Sau rất nhiều thất vọng, tôi phát hiện ra rằng điều này tạo ra kết quả kỳ lạ:
id in (thập phân.Decimal)
in id(loại(o))
Người ta mong đợi id giống nhau vì điều đó có nghĩa là cùng một đối tượng lớp chỉ tồn tại một lần trong bộ nhớ. Vì id khác nhau nênisinstance()
不起作用。
Có thể là số thập phân đó đã được nhập ở nơi khác, chẳng hạn như trong gói App Engine và/hoặc webapp2?
Mô-đun sau tái tạo lỗi trên hệ thống của tôi (OSx 10.10, Python 2.7.6, GAE SDK 1.9.20). Chỉ cần tạo một ứng dụng GAE và đặt nó vào main.py:
nhập webapp2, thập phân, json, MySQLdb, sys
lớp DecimalEncoding(json.JSONEncode):
mặc định mặc định (tự, o):
id in (thập phân.Decimal)
in id(loại(o))
nếu isinstance(o, thập phân. Thập phân):
trả về float(o)
trả về super(DecimalEncode, self).default(o)
lớp MainHandler (webapp2.RequestHandler):
chắc chắn nhận được (tự):
db = MySQLdb.connect(unix_socket='/var/mysql/mysql.sock', Host='localhost', user='root', db='ssss', charset='utf8')
con trỏ = db.cursor(MySQLdb.cursors.DictCursor)
con trỏ.execute("CHỌN id, giá TỪ sản phẩm WHERE id = 1")
bản ghi = con trỏ.fetchone()
self.response.headers['Content-Type'] = 'application/json'
self.response.write(json.dumps(
ghi,
cls=Bộ mã hóa thập phân,
thụt lề=4,
dấu phân cách=(',', ': ')
))
ứng dụng = webapp2.WSGIApplication([
('/', MainHandler)
], gỡ lỗi=Đúng)
Bảng cơ sở dữ liệu:
TẠO BẢNG `sản phẩm` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`price` thập phân(10,2) không dấu DEFAULT NULL,
PRIMARY KEY (`id`)
) ĐỘNG CƠ=InnoDB AUTO_INCREMENT=0 CHARSET MẶC ĐỊNH=utf8;
CHÈN VÀO GIÁ TRỊ sản phẩm (0, 5,00);
Có vẻ như thập phân.Decimal
Lớp trong SDK Google App Engineở đâu đóĐã vá (hoặc tải lại mô-đun), đây là quá trình nhập thư viện được thực hiện giữa các chuyển đổi MySQL decimal
Giống như cái bạn đã nhập.
May mắn thay, chúng ta có thể giải quyết vấn đề này bằng cách cập nhật bảng dịch MySQL:
từ MySQLdb.constants nhập FIELD_TYPE
từ chuyển đổi nhập MySQLdb.converters
nhập số thập phân
chuyển đổi[FIELD_TYPE.DECIMAL] = chuyển đổi[FIELD_TYPE.NEWDECIMAL] = thập phân.Decimal
Vậy là xong; đoạn mã trên sẽ đặt lại lớp MySQL và việc kiểm tra loại bộ mã hóa JSON của bạn đã thành công.
Một cách khác là tìm MySQLdb
Các lớp đang sử dụng:
lớp DecimalEncoding(json.JSONEncode):
mặc định mặc định (tự, o):
nếu isinstance(o, MySQLdb.converters.conversions[MySQLdb.constants.FIELD_TYPE.DECIMAL]):
trả về float(o)
trả về super(DecimalEncode, self).default(o)
Tôi là một lập trình viên xuất sắc, rất giỏi!