이해력은 이해 범위 이후에도 이름을 리 바인드합니다. 이게 옳은 거니?
이해가 범위와 상호 작용하고 있습니다. 이것이 예상되는 동작입니까?
방법이 있습니다.
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
'IT' 카테고리의 다른 글
SQL에서 뷰에 서열 변수를 있습니까? (0) | 2020.07.20 |
---|---|
무시 된 파일을 마이너스 상태에서 유지 (0) | 2020.07.20 |
판매에 HTTP 상태 코드 201 반환 (0) | 2020.07.20 |
Java8에서 void (void가 아닌) 메소드에 함수 유형을 지정하는 방법은 무엇입니까? (0) | 2020.07.20 |
오류 :이 범위에서 'NULL'이 유효하지 않습니다. (0) | 2020.07.20 |