Возможно ли иметь функцию в Python, где fun(1+1) поступает в функцию как '1+1', а не как 2?
Здравый смысл подсказывает, что это невозможно, потому что нет способа предотвратить вычисление 1+1 до того, как оно будет передано в функцию.
Но тот же здравый смысл подсказывает, что следующий PHP-код не должен работать, потому что unset($arr[0]) должен быть таким же, как unset(99). Но это работает, и последнее является синтаксической ошибкой.
$arr = [99, 1, 2, 3, 99];
unset($arr[0]); # remove the first element
$arr = array_values($arr); # reindex from 0
echo $arr == [1, 2, 3, 99]; # yes
Так что, возможно, в Python тоже есть лазейка для подобных странностей.
Я хотел бы использовать это для написания более коротких тестов. На данный момент у меня есть:
with pytest.raises(ZeroDivisionError):
1/0
with pytest.raises(ZeroDivisionError):
0/0
with pytest.raises(ZeroDivisionError):
0**-1
with pytest.raises(FooError):
Foo(round_hole=SquarePeg)
with pytest.raises(FooError):
Foo(give_me_five=6)
Вместо этого я бы предпочел написать:
shorter(ZeroDivisionError, [1/0, 0/0, 0**-1])
shorter(FooError, [
Foo(round_hole=SquarePeg),
Foo(give_me_five=6)
])
Конечно, я мог бы передавать строки, но недостаток утраченной подсветки синтаксиса свел бы на нет преимущество краткости.
Возможно, не такая уж плохая идея «открыть» тестовый файл из тестового режима в режим записи, сделав замену строк, например
', # expr\n ' в '", # expr\n "'.
# write mode
shorter(FooError, [ # except
Foo(round_hole=SquarePeg), # expr
Foo(give_me_five=6) # expr
])
# test mode
shorter(FooError, [ # except
"Foo(round_hole=SquarePeg)", # expr
"Foo(give_me_five=6)" # expr
])
На самом деле лямбда-подход, предложенный Хофлингом, работает нормально. Обычно отсутствие аргументов вызывает ошибку прямо в тестовом файле. Чтобы избежать этого, используйте __init__(self, arg=None) вместо просто __init__(self, arg).
Определение более коротких и примеров классов:
import pytest
from inspect import isclass
def shorter(expected, values):
if isclass(expected) and issubclass(expected, Exception):
for value in values:
with pytest.raises(expected):
value()
else:
for value in values:
assert value == expected
class Hand():
def __init__(self, give_me_five=None):
if give_me_five is None:
raise NoArgError
if give_me_five != 5:
raise NotFiveError
self.twice_five = 2 * give_me_five
class NoArgError(ValueError):
"""You need to provide and argument."""
class NotFiveError(ValueError):
"""The argument must be 5."""
Пример тестового файла:
from .other_file import shorter, Hand, NoArgError, NotFiveError
def test_errors():
check(NoArgError, [
lambda: Hand()
])
check(NotFiveError, [
lambda: Hand(0),
lambda: Hand(6),
lambda: Hand(''),
lambda: Hand('5')
])
def test_values():
check(10, [
Hand(5).twice_five
])
Подробнее здесь: https://stackoverflow.com/questions/613 ... -as-a-stri
Могу ли я передать невычисленное выражение в качестве аргумента функции, а не как строку? ⇐ Python
Программы на Python
1767536944
Anonymous
Возможно ли иметь функцию в Python, где fun(1+1) поступает в функцию как '1+1', а не как 2?
Здравый смысл подсказывает, что это невозможно, потому что нет способа предотвратить вычисление 1+1 до того, как оно будет передано в функцию.
Но тот же здравый смысл подсказывает, что следующий PHP-код не должен работать, потому что unset($arr[0]) должен быть таким же, как unset(99). Но это работает, и последнее является синтаксической ошибкой.
$arr = [99, 1, 2, 3, 99];
unset($arr[0]); # remove the first element
$arr = array_values($arr); # reindex from 0
echo $arr == [1, 2, 3, 99]; # yes
Так что, возможно, в Python тоже есть лазейка для подобных странностей.
Я хотел бы использовать это для написания более коротких тестов. На данный момент у меня есть:
with pytest.raises(ZeroDivisionError):
1/0
with pytest.raises(ZeroDivisionError):
0/0
with pytest.raises(ZeroDivisionError):
0**-1
with pytest.raises(FooError):
Foo(round_hole=SquarePeg)
with pytest.raises(FooError):
Foo(give_me_five=6)
Вместо этого я бы предпочел написать:
shorter(ZeroDivisionError, [1/0, 0/0, 0**-1])
shorter(FooError, [
Foo(round_hole=SquarePeg),
Foo(give_me_five=6)
])
Конечно, я мог бы передавать строки, но недостаток утраченной подсветки синтаксиса свел бы на нет преимущество краткости.
Возможно, не такая уж плохая идея «открыть» тестовый файл из тестового режима в режим записи, сделав замену строк, например
', # expr\n ' в '", # expr\n "'.
# write mode
shorter(FooError, [ # except
Foo(round_hole=SquarePeg), # expr
Foo(give_me_five=6) # expr
])
# test mode
shorter(FooError, [ # except
"Foo(round_hole=SquarePeg)", # expr
"Foo(give_me_five=6)" # expr
])
На самом деле лямбда-подход, предложенный Хофлингом, работает нормально. Обычно отсутствие аргументов вызывает ошибку прямо в тестовом файле. Чтобы избежать этого, используйте __init__(self, arg=None) вместо просто __init__(self, arg).
Определение более коротких и примеров классов:
import pytest
from inspect import isclass
def shorter(expected, values):
if isclass(expected) and issubclass(expected, Exception):
for value in values:
with pytest.raises(expected):
value()
else:
for value in values:
assert value == expected
class Hand():
def __init__(self, give_me_five=None):
if give_me_five is None:
raise NoArgError
if give_me_five != 5:
raise NotFiveError
self.twice_five = 2 * give_me_five
class NoArgError(ValueError):
"""You need to provide and argument."""
class NotFiveError(ValueError):
"""The argument must be 5."""
Пример тестового файла:
from .other_file import shorter, Hand, NoArgError, NotFiveError
def test_errors():
check(NoArgError, [
lambda: Hand()
])
check(NotFiveError, [
lambda: Hand(0),
lambda: Hand(6),
lambda: Hand(''),
lambda: Hand('5')
])
def test_values():
check(10, [
Hand(5).twice_five
])
Подробнее здесь: [url]https://stackoverflow.com/questions/61383068/can-i-pass-an-unevaluated-expression-as-argument-to-a-function-besides-as-a-stri[/url]
Ответить
1 сообщение
• Страница 1 из 1
Перейти
- Кемерово-IT
- ↳ Javascript
- ↳ C#
- ↳ JAVA
- ↳ Elasticsearch aggregation
- ↳ Python
- ↳ Php
- ↳ Android
- ↳ Html
- ↳ Jquery
- ↳ C++
- ↳ IOS
- ↳ CSS
- ↳ Excel
- ↳ Linux
- ↳ Apache
- ↳ MySql
- Детский мир
- Для души
- ↳ Музыкальные инструменты даром
- ↳ Печатная продукция даром
- Внешняя красота и здоровье
- ↳ Одежда и обувь для взрослых даром
- ↳ Товары для здоровья
- ↳ Физкультура и спорт
- Техника - даром!
- ↳ Автомобилистам
- ↳ Компьютерная техника
- ↳ Плиты: газовые и электрические
- ↳ Холодильники
- ↳ Стиральные машины
- ↳ Телевизоры
- ↳ Телефоны, смартфоны, плашеты
- ↳ Швейные машинки
- ↳ Прочая электроника и техника
- ↳ Фототехника
- Ремонт и интерьер
- ↳ Стройматериалы, инструмент
- ↳ Мебель и предметы интерьера даром
- ↳ Cантехника
- Другие темы
- ↳ Разное даром
- ↳ Давай меняться!
- ↳ Отдам\возьму за копеечку
- ↳ Работа и подработка в Кемерове
- ↳ Давай с тобой поговорим...
Мобильная версия