Why doesn't a dictionary work in classes?

Peter Otten __peter__ at web.de
Tue Dec 25 16:09:30 EST 2018


אורי wrote:

> Why does this not work:
> 
> class User(ValidateUserPasswordMixin, PermissionsMixin, Entity,
> AbstractBaseUser):

>     GENDER_VALID_VALUES = [choice[0] for choice in GENDER_CHOICES]
>     GENDERS_DICT = {GENDER_FEMALE: GENDER_FEMALE_STRING, GENDER_MALE:

>     ALL_GENDERS = [GENDERS_DICT[gender] for gender in GENDER_VALID_VALUES]
> 
> (it throws an exception: `NameError: name 'GENDERS_DICT' is not defined`)

The list comprehension in Python 3 works like a generator generator 
expression:

https://www.python.org/dev/peps/pep-0289/?modTest=#the-details

In your case GENDER_VALID_VALUES is looked up in the class, and GENDERS_DICT 
is looked up in the function synthesized from the list comprehension.
As with methods this function only sees the local and the global namespace, 
but not the class namespace.

I realise that this is a long-winded way of saying "it is like it is",
but maybe it helps you understand what works and what doesn't.
This would work for example (not recommended for actual use):

    ALL_GENDERS = [
        GENDERS_DICT[gender] for gender, GENDERS_DICT in
        zip(GENDER_VALID_VALUES, itertools.repeat(GENDERS_DICT))
    ]


> But this works:

> User.ALL_GENDERS = [User.GENDERS_DICT[gender] for gender in
> User.GENDER_VALID_VALUES]

User exists in the global namespace, and has both attributes, so no 
surprises here.



More information about the Python-list mailing list