[Tutor] How to avoid "UnboundLocalError: local variable 'goal_year' referenced before assignment"?
Cameron Simpson
cs at cskk.id.au
Sun Mar 24 18:04:21 EDT 2019
On 24Mar2019 14:33, boB Stepp <robertvstepp at gmail.com> wrote:
>> On 23Mar2019 22:15, boB Stepp <robertvstepp at gmail.com> wrote:
>>
>> The lambda is just a single line function definition, and doesn't get a
>> function name.
>
>> So your get_input name now accepts a "date_constructor" parameter and
>> you would change the input step from this:
>>
>> try:
>> identifier = int(input(input_prompt))
>> if date_value_err_ck:
>> date(*date_value_err_ck)
>> except ValueError:
>>
>> to this:
>>
>> try:
>> value = int(input(input_prompt))
>> date = date_constructor(value)
>> except ValueError:
>
>You could not know this from the code I showed (As I pared it down to
>illustrate my problem.), but I am also using get_input() to pull in
>from the user non-date values, too, but they are also all integers:
>pages_read and total_pages_to_read. Because of this, for these latter
>two items, "date_value_err_ck" will be assigned "None", which is why I
>have the "if date_value_err_ck:".
Ok. So I realised later that you're not using the date from
date_constructor; you're just calling it to see if it raises ValueError
as a sanity check.
Why not make that a condition, and drop date_value_err_ck altogether?
'conditions': [
(lambda goal_year: datetime.date(goal_year, 1, 1),
"This doesn't look like a valid date year to datetime.date()."),
and make the condition checking code more robust:
for bad_condition, message in conditions:
try:
badness = bad_condition(input_value)
except ValueError as e:
print("Invalid goal_year, cannot even run the condition check! " + str(e))
else:
if badness:
print(message)
That reduces your opening try/except to just checking that the input is
a valid int, a lot simpler.
>> Well, when you define the goal_month constructor lambda function,
>> goal_year _is_ a local variable. And _because_ it is not a parameter of
>> the lambda, the lambda finds it in the scope where it was defined: the
>> scope at the bottom of your programme.
>>
>> This is called a "closure": functions has access to the scope they are
>> define in for identifiers not locally defined (eg in the parameters or
>> the function local variables - which are those assigned to in the code).
>
>This is so cool and useful! I recall seeing this mentioned for nested
>functions, but did not know it worked for lambdas as well.
Lambda are functions. Same rules.
Cheers,
Cameron Simpson <cs at cskk.id.au>
More information about the Tutor
mailing list