атрибуты класса python3 scope [duplicate]

Хотя принятый ответ потрясающий. Я также хотел бы поделиться быстрым взломом для этой проблемы. (Это также заботится об отрицательной возрастной проблеме.)

f=lambda age: (age.isdigit() and ((int(age)>=18  and "Can vote" ) or "Cannot vote")) or \
f(raw_input("invalid input. Try again\nPlease enter your age: "))
print f(raw_input("Please enter your age: "))

P.S. Этот код предназначен для python 2.x и может быть экспортирован в 3.x путем изменения функций raw_input и печати. ​​

113
задан Martijn Pieters 29 March 2014 в 02:22
поделиться

3 ответа

152
ответ дан user2357112 19 August 2018 в 02:35
поделиться

Принятый ответ обеспечивает отличную информацию, но здесь, похоже, есть несколько других морщин - различия между пониманием списка и выражениями генератора. Демонстрация, с которой я играл:

class Foo:

    # A class-level variable.
    X = 10

    # I can use that variable to define another class-level variable.
    Y = sum((X, X))

    # Works in Python 2, but not 3.
    # In Python 3, list comprehensions were given their own scope.
    try:
        Z1 = sum([X for _ in range(3)])
    except NameError:
        Z1 = None

    # Fails in both.
    # Apparently, generator expressions (that's what the entire argument
    # to sum() is) did have their own scope even in Python 2.
    try:
        Z2 = sum(X for _ in range(3))
    except NameError:
        Z2 = None

    # Workaround: put the computation in lambda or def.
    compute_z3 = lambda val: sum(val for _ in range(3))

    # Then use that function.
    Z3 = compute_z3(X)

    # Also worth noting: here I can refer to XS in the for-part of the
    # generator expression (Z4 works), but I cannot refer to XS in the
    # inner-part of the generator expression (Z5 fails).
    XS = [15, 15, 15, 15]
    Z4 = sum(val for val in XS)
    try:
        Z5 = sum(XS[i] for i in range(len(XS)))
    except NameError:
        Z5 = None

print(Foo.Z1, Foo.Z2, Foo.Z3, Foo.Z4, Foo.Z5)
1
ответ дан FMc 19 August 2018 в 02:35
поделиться

В основном это проблема в Python 3. Я надеюсь, что они меняют ее.

Bugged (работает в версии 2.7):

x = 4
y = [x+i for i in range(1)]

Чтобы обойти это (работает в 3+) :

x = 4
y = (lambda x=x: [x+i for i in range(1)])()
5
ответ дан Jonathan 19 August 2018 в 02:35
поделиться
  • 1
    Проблема присутствует и в Python 2, при использовании выражений генератора, а также при использовании понятий set и dictionary. Это не ошибка, это следствие того, как работают пространства имен классов. Это не изменится. – Martijn Pieters♦ 16 July 2015 в 13:20
  • 2
    И я отмечаю, что ваше обходное решение делает именно то, что уже сказано в моем ответе: создайте новую область (здесь нет никакой возможности использовать lambda, используя def для создания функции). – Martijn Pieters♦ 14 April 2017 в 11:31
  • 3
    Ага. Хотя хорошо иметь ответ с обходом с первого взгляда, он однозначно указывает на поведение как на ошибку, когда это побочный эффект от того, как работает язык (и, следовательно, не будет изменен) – jsbueno 6 November 2017 в 02:16
  • 4
    Это другая проблема, которая на самом деле не проблема в Python 3. Она возникает только в IPython, когда вы вызываете ее в режиме вставки, используя say python -c "import IPython;IPython.embed()". Запустите IPython напрямую, используя say ipython, и проблема исчезнет. – Riaz Rizvi 28 July 2018 в 01:07
Другие вопросы по тегам:

Похожие вопросы: