Похоже, вы правы:
>>> import numpy
>>> import json
>>> json.dumps(numpy.int32(685))
Traceback (most recent call last):
File "", line 1, in
File "/usr/lib/python2.7/json/__init__.py", line 243, in dumps
return _default_encoder.encode(obj)
File "/usr/lib/python2.7/json/encoder.py", line 207, in encode
chunks = self.iterencode(o, _one_shot=True)
File "/usr/lib/python2.7/json/encoder.py", line 270, in iterencode
return _iterencode(o, 0)
File "/usr/lib/python2.7/json/encoder.py", line 184, in default
raise TypeError(repr(o) + " is not JSON serializable")
TypeError: 685 is not JSON serializable
Прискорбно, что число «__repr__
не дает вам никаких намеков на то, что они типа они , Они бегают, маскируясь под int
, когда их нет ( ахает ). В конечном счете, похоже, что json
говорит вам, что int
не сериализуем, но на самом деле, он говорит вам, что этот конкретный np.int32 (или любой другой тип, который у вас есть на самом деле) не сериализуем. (Ничего удивительного в этом нет - np.int32 не является сериализуемым). По этой же причине изречение, которое вы неизбежно напечатали перед передачей его в json.dumps
, выглядит так, как будто в нем тоже есть целые числа.
Самый простой обходной путь - это, вероятно, написать свой собственный сериализатор 1 sup>:
class MyEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, numpy.integer):
return int(obj)
elif isinstance(obj, numpy.floating):
return float(obj)
elif isinstance(obj, numpy.ndarray):
return obj.tolist()
else:
return super(MyEncoder, self).default(obj)
Вы используете его так:
json.dumps(numpy.float32(1.2), cls=MyEncoder)
json.dumps(numpy.arange(12), cls=MyEncoder)
json.dumps({'a': numpy.int32(42)}, cls=MyEncoder)
и т.д.
1 sup> Или вы можете просто написать функцию по умолчанию и передать ее в качестве аргумента ключевого слова defaut
в json.dumps
. В этом случае вы бы заменили последнюю строку на raise TypeError
, но ... ме. Класс более расширяемый: -) sup>
Вы можете обмануть, просто имея составную функцию, которая вызывает другие функции.
document.getElementById("selectbox1").onchange = function() {
function1();
function2();
}
Вы также можете использовать шаблон наблюдателя, описанный в книге Pro JavaScript Design Patterns . У меня есть пример его использования в статье ( здесь ).
//– publisher class —
function Publisher() {
this.subscribers = [];
};
Publisher.prototype.deliver = function(data) {
this.subscribers.forEach(function(fn) { fn(data); });
};
//– subscribe method to all existing objects
Function.prototype.subscribe = function(publisher) {
var that = this;
var alreadyExists = publisher.subscribers.some(function(el) {
if (el === that) {
return;
}
});
if (!alreadyExists) {
publisher.subscribers.push(this);
}
return this;
};
Можете ли вы использовать jQuery? Это позволит вам довольно легко связывать / управлять / отменять привязку событий. Единственная загвоздка в том, что обработчики событий активируются в том порядке, в котором они связаны.
if (<certain conditions>) {
$("#selectbox1").bind("change", eventdata, function1);
}
if (<other conditions>) {
$("#selectbox1").bind("change", eventdata, function1);
}
И вы также можете изучить возможность запуска пользовательских событий, если ваши потребности являются сложными. Например, вместо «интерпретации» onChange, возможно, есть способ специально запускать пользовательские события. См. последний пример на странице jQuery.
Если вы используете jQUery, у вас будет что-то вроде
<select id="selectbox1">
<option>...</option>
<option>...</option>
</select>
if (<certain conditions>) {
$("#selectbox1").change(function () {
//hides elements to reduce clutter on a web form ...
});
}
....
if (<other conditions>) {
$("#selectbox1").change(function () {
//set global variable to false
});
}
Это в основном также позаботится о совместимости браузера.
В настоящее время существует три различных метода определения обработчиков событий (функция, которая запускается при обнаружении определенного события): традиционный метод, метод W3C и метод Microsoft.
Традиционный метод
В традиционном методе обработчики событий определяются установкой свойства on event элемента в Javascript (как вы делаете в своем примере кода) или установкой on атрибут события в теге HTML (например,
). Хотя это самый простой в использовании метод, его использование сейчас, как правило, не одобряется, поскольку, как вы обнаружили, он довольно жесткий - нелегко добавлять и удалять обработчики событий для элемента, к которому уже прикреплен обработчик событий. Также, смешивание javascript с HTML больше не считается надлежащей практикой; скорее, он должен содержаться внутри или загружаться через тег