IT

이해력은 이해 범위 이후에도 이름을 리 바인드합니다.

lottoking 2020. 7. 20. 07:18
반응형

이해력은 이해 범위 이후에도 이름을 리 바인드합니다. 이게 옳은 거니?


이해가 범위와 상호 작용하고 있습니다. 이것이 예상되는 동작입니까?

방법이 있습니다.

def leave_room(self, uid):
  u = self.user_by_id(uid)
  r = self.rooms[u.rid]

  other_uids = [ouid for ouid in r.users_by_id.keys() if ouid != u.uid]
  other_us = [self.user_by_id(uid) for uid in other_uids]

  r.remove_user(uid) # OOPS! uid has been re-bound by the list comprehension above

  # Interestingly, it's rebound to the last uid in the list, so the error only shows
  # up when len > 1

징징의 위험이있는 이는 잔인한 오류의 원인입니다. 새 코드를 사용하는 경우 리 바인딩으로 인해 매우 이상한 오류가 발생합니다. 심지어 문제라는 것을 알고 있습니다. "항상 밑줄로 목록 이해에 임시 변수를 머리말"과 같은 규칙을 따르지만, 그조차도 완전하게.

이 무작위 시한 폭탄 대기 유형이 사실은 목록 이해의 모든 "사용 편의성"을 무효화합니다.


목록 함축 파이썬 2의 루프 제어 변수를 누설하지만 파이썬 3에서 다음의 귀도 반 로섬 (파이썬의 창조자) 설명 이 뒤 6 역사를 :

또한 Python 3에서 다른 변경을 수행했습니다. 용어 2에서,리스트 이해는 루프 제어 변수를 주변 범위로 "누설"합니다.

x = 'before'
a = [x for x in 1, 2, 3]
print x # this prints '3', not 'before'

이것은 이해의 원래 구현의 결과였습니다. "더러운 작은 비밀"중 하나였습니다. 목록 이해력을 맹목적으로 신속하게 만들기위한 의도적 인 타협으로 시작되는 것이지만 함정이 아니지만 사람들을 괴롭 히고 있습니다. 생성기에서 수행 할 수 없습니다. 생성기 생성기는 생성기를 사용하여 구현하고, 별도의 실행 프레임이 필요합니다. 내가 사용하는 경우에 사용하는 경우에 사용하는 경우

그러나 파이썬 3에서는 생성자 수정하기와 동일한 구현 전략을 사용하여 목록 이해의 "더러운 비밀"을 결정했습니다. 따라서 Python 3에서 위의 예제 (print (x) :-를 사용하도록 수정 한 후)는 'before'를 인쇄하여 목록 이해의 'x'가 일시적으로 음영을 표시하지만 주변의 'x'를 재정의합니다 . 범위.


예, for 루프와 많음 2.x에서 변수를 "누설"목록을 작성하십시오.

돌이켜 보면 실수로 인식 생성기 표현에서 피했습니다. 편집 : Matt B.에 따르면 Python 3에서 사전 및 사전 이해 구문이 백 포트 될 때 피했습니다.

2리스트에서와 같이 그대로 두어야 만 성능을 발휘합니다.

이것은 다음의 모든 것을 의미합니다.

list(x for x in a if x>32)
set(x//4 for x in a if x>32)         # just another generator exp.
dict((x, x//16) for x in a if x>32)  # yet another generator exp.
{x//4 for x in a if x>32}            # 2.7+ syntax
{x: x//16 for x in a if x>32}        # 2.7+ syntax

x파일은 항상 루트에 로컬입니다.

[x for x in a if x>32]
set([x//4 for x in a if x>32])         # just another list comp.
dict([(x, x//16) for x in a if x>32])  # yet another list comp.

파이썬 2.X에서는 x변수가 주변 범위로 누출 됩니다.


파이썬 3.8에 대한 업데이트 (?) : PEP 572이해력과 생성기 표현에서 의도적으로 누출 되는 :=할당 연산자를 소개 합니다 ! 그것은 본질적으로 2 가지 유스 케이스에 의해 동기를 부여 받았다 : and와 같은 조기 종료 기능을 "증인"을 수행하는 것 :any()all()

if any((comment := line).startswith('#') for line in lines):
    print("First comment:", comment)
else:
    print("There are no comments")

변경 가능한 상태 업데이트 :

total = 0
partial_sums = [total := total + v for v in values]

범위 지정 정확한 부록 B참조하십시오 . 변수는 주변의 가장 가까운 할당 def하거나 lambda그 기능을 선언하지 않는 한, nonlocal또는 global.


예, for루프 에서 할당이 발생합니다 . 새로운 범위가 생성되지 않습니다.

이것은 분명히 예상되는 동작입니다. 각주기마다 값이 및 이름에 바인딩됩니다. 예를 들어

>>> x=0
>>> a=[1,54,4,2,32,234,5234,]
>>> [x for x in a if x>32]
[54, 234, 5234]
>>> x
5234

그것은 쉬운 인식 널 피하는 것이 쉬운 것처럼. 이해 내의 변수에 기존 이름을 사용하지 않습니다.


흥미롭게도이 사전이나 세트 이해에 영향을 미치게됩니다.

>>> [x for x in range(1, 10)]
[1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> x
9
>>> {x for x in range(1, 5)}
set([1, 2, 3, 4])
>>> x
9
>>> {x:x for x in range(1, 100)}
{1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7, 8: 8, 9: 9, 10: 10, 11: 11, 12: 12, 13: 13, 14: 14, 15: 15, 16: 16, 17: 17, 18: 18, 19: 19, 20: 20, 21: 21, 22: 22, 23: 23, 24: 24, 25: 25, 26: 26, 27: 27, 28: 28, 29: 29, 30: 30, 31: 31, 32: 32, 33: 33, 34: 34, 35: 35, 36: 36, 37: 37, 38: 38, 39: 39, 40: 40, 41: 41, 42: 42, 43: 43, 44: 44, 45: 45, 46: 46, 47: 47, 48: 48, 49: 49, 50: 50, 51: 51, 52: 52, 53: 53, 54: 54, 55: 55, 56: 56, 57: 57, 58: 58, 59: 59, 60: 60, 61: 61, 62: 62, 63: 63, 64: 64, 65: 65, 66: 66, 67: 67, 68: 68, 69: 69, 70: 70, 71: 71, 72: 72, 73: 73, 74: 74, 75: 75, 76: 76, 77: 77, 78: 78, 79: 79, 80: 80, 81: 81, 82: 82, 83: 83, 84: 84, 85: 85, 86: 86, 87: 87, 88: 88, 89: 89, 90: 90, 91: 91, 92: 92, 93: 93, 94: 94, 95: 95, 96: 96, 97: 97, 98: 98, 99: 99}
>>> x
9

언급 된 언급 한대로 3으로 수정되었습니다.


이 동작이 설치되지 않은 사양 2.6의 경우 몇 가지 해결 방법

# python
Python 2.6.6 (r266:84292, Aug  9 2016, 06:11:56)
Type "help", "copyright", "credits" or "license" for more information.
>>> x=0
>>> a=list(x for x in xrange(9))
>>> x
0
>>> a=[x for x in xrange(9)]
>>> x
8

참고 URL : https://stackoverflow.com/questions/4198906/list-comprehension-rebinds-names-even-after-scope-of-comprehension-is-this-righ

반응형