Этот подход работал для меня.
var ObjectId = require('mongodb').ObjectID;
var get_by_id = function(id, callback) {
console.log("find by: "+ id);
get_collection(function(collection) {
collection.findOne({"_id": new ObjectId(id)}, function(err, doc) {
callback(doc);
});
});
}
Передайте аргумент функции в str и выполните exec внутри функции
def try_or_zero(exp):
try:
exec(exp)
return exp
except:
return 0
, чтобы ваш вызов функции был похож на ниже try_or_zero ('1 == 2')
Кажется, проблема в том, что python не имеет какой-либо формы отложенной оценки
blockquote>Ошибка ... да, но, возможно, не в той форме, которую вы ожидаете. Аргументы функции действительно перед вычислением передаются в функцию eval'd, поэтому
try_or_zero(foo.bar())
будут действительно выполняться следующим образом:
param = foo.bar() try_or_zero(param)
Теперь функции Python являются простыми объектами (их можно использовать как переменные, передаваемые в качестве аргументов функциям и т. д.), и они вызываются только при применении оператора вызова (парены, с или без аргументов), так что вы можете передать функцию в
try_or_zero
и позволитьtry_or_zero
вызвать функцию:def try_or_zero(func): try: return func() except Exception as e: return 0
Теперь вы возразите, что 1 / это не сработает, если функция ожидает аргументы, а 2 / необходимость написать функцию только для этого - это PITA - и оба возражения верны. Надеемся, что в Python также есть ярлык для создания простых анонимных функций, состоящих из одного (даже если сколь угодно сложного) выражения:
lambda
. Кроме того, функции python (включая «лямбда-функции», которые, технически, являются простыми функциями) являются замыканиями - они захватывают контекст, в котором они определены, - так что довольно легко обернуть все это вместе:[ 1116] Дополнительное замечание об обработке исключений:a = 42 b = "c" def add(x, y): return x + y result = try_or_zero(lambda: add(a, b))
Сначала не используйте голое, кроме как минимум catch
Exception
(иначе вы можете помешать некоторому исключению - например,SysExit
- работать как положено). 1117]Также желательно ловить только те исключения, которые вы ожидаете в данной точке. В вашем случае вы можете захотеть передать набор исключений, которые вы хотите игнорировать, например:
def try_or_zero(func, *exceptions): if not exceptions: exceptions = (Exception,) try: return func() except exceptions as e: return 0 a = 42 b = "c" def add(x, y): return x + y result = try_or_zero(lambda: add(a, b), TypeError))
, которые не позволят вашему коду маскировать непредвиденные ошибки.
И, наконец: вы также можете добавить поддержку возвращаемого значения, отличного от нуля, в случае исключения (не все выражения должны возвращать int):
# XXX : python3 only, python2 doesn't accept # keyword args after *args def try_or(func, *exceptions, default=0): if not exceptions: exceptions = (Exception,) try: return func() except exceptions as e: return 0 # adding lists is legit too, # so here you may want an empty list as the return value # instead a = [1, 2, 3] # but only to lists b = "" result = try_or(lambda: a + b, TypeError, default=[]))
Не нужно беспокоиться о exec
и прочем, используйте тот факт, что функции python являются объектами и, таким образом, могут передаваться как аргументы
def try_or_zero(exp):
try:
return exp()
except:
return 0
И просто вызвать try_or_zero(my_awesome_func)
(без () ваш метод)