Ошибка, которую вы получаете при попытке запустить код:
UnboundLocalError: local variable 'a' referenced before assignment
... который, на первый взгляд, кажется странным: ведь сначала в коде выше (a = 15
) является назначением. Итак, что происходит?
На самом деле происходит две разные вещи, и ни одна из них не очевидна, если вы уже не знаете о них.
Прежде всего, у вас на самом деле есть два различные переменные:
a
в вашей первой строке - это глобальная переменная (так называемая, поскольку она существует в глобальной области, за пределами любых определений функций). a
в других строках является локальной переменной, что означает, что она существует только внутри вашей функции test()
. Эти две переменные полностью не связаны друг с другом, хотя они одно и то же имя.
Переменная локальна для функции, если в ней есть оператор, назначающий ее внутри - например, ваша a = a +10
строка.
Тем не менее, ошибка все еще выглядит странно - в конце концов, самое первое, что вы делаете внутри test()
, присваивается a
, поэтому как его можно называть заранее?
Ответ заключается в том, что в инструкции присваивания Python оценивает все, что находится справа ide знака =
, прежде чем назначать его имени с левой стороны - так что, хотя назначение записано сначала в вашем коде, a
получает , на которое ссылается сначала в этой правой части: a +10
.
Есть два способа обойти это. Во-первых, чтобы сказать Python, что вы действительно хотите, чтобы a
внутри test()
были одинаковыми a
в глобальной области:
def test():
global a
a = a + 10
print(a)
Это будет работать, но это довольно плохо писать программы. Изменение глобальных переменных внутри функций затрудняет управление очень быстро, потому что у вас обычно есть много функций, и никто из них никогда не может быть уверен, что другой не возится с глобальной переменной, каким-то образом они не ожидают.
Лучше всего передать переменные в качестве аргументов для функций, например:
a = 15
def test(x):
x = x + 10
print(x)
test(a)
Обратите внимание, что имя не должно быть одинаковым - ваше новое определение test()
просто говорит, что он принимает значение, а затем что-то делает с ним. Вы можете передать все, что захотите - это может быть a
, или число 7
, или что-то еще. Фактически, ваш код всегда будет легче понять, если вы попытаетесь избежать наличия переменных с тем же именем в разных областях.
Если вы играете с приведенным выше кодом, вы заметите что-то интересное:
>>> a = 15
>>> test(a)
25
>>> a
15
... a
не изменился! Это потому, что, хотя вы передали его в test()
, и его присвоили x
, он был изменен x
, оставив только оригинальный a
.
Если вы хотите фактически изменить a
, вам нужно вернуть измененную функцию x
из функции, а затем переназначить ее обратно на a
снаружи:
>>> a = 15
>>>
>>> def test(x):
... x = x + 10
... print(x)
... return x
...
>>> a = test(a)
25
>>> a
25
Google всё ещё твой друг. Есть несколько человек, которые исследовали темы для лучшей среды тестирования e2e для приложений JavaScript: https://blog.bitsrc.io/top-javascript-testing-frameworks-in-demand-for-2019-90c76e7777e9 [ 110] https://www.reddit.com/r/javascript/comments/8oorxa/what_are_best_endtoend_testing_frameworks_these/ https://medium.com/welldone-software/an-overview-of-javascript -testing-in-2018-f68950900bc3
Мы сделали выбор между Cypress и TestCafe и выбрали Cypress, поскольку он делает больше вещей «волшебным образом» для вас. Это приводит к меньшей потребности в навыках программирования.