2013-03-19 3 views
2

내가 오류파이썬 : 다음 함수를 실행하는 동안 할당 오류 전에 참조 된 지역 변수는

UnboundLocalError: local variable 'new_speedDx' referenced before assignment

을 가지고 계속 :이 기능에

def new_speedD(boid1): 
    bposx = boid1[0] 
    if bposx < WALL: 
     new_speedDx = WALL_FORCE 
    elif bposx > WIDTH - WALL: 
     new_speedDx = -WALL_FORCE 

    bposy = boid1[1] 
    if bposy < WALL: 
     new_speedDy = WALL_FORCE 
    elif bposx > WIDTH - WALL: 
     new_speedDy = -WALL_FORCE 

    return new_speedDx, new_speedDy 

을 boid1 4 개 요소와 벡터 (이다 xpos, ypos, xvelocity, yvelocity)이고 대문자의 모든 변수는 상수 (숫자)입니다. 누구든지이 문제를 해결하는 방법을 알고 있습니까? 인터넷에서 가능한 많은 솔루션을 찾았지만 아무 것도 작동하지 않는 것 같았습니다.

+2

'bposx = boid1 [0]'과'bposy = boid1 [1]'은 압축을 풀어서 더 잘 쓸 수 있습니다 :'bposx, bposy = boid1'. –

+0

그리고 다른 두 요소는? – user2089012

+0

더 큰 튜플 인 경우, 3.x에서는'_'에 목록으로 추가 값을 할당하는'bposx, bposy, * _ = boid1'을 수행 할 수 있습니다 (보통 버려지는 값을 나타내는 데 사용됩니다). 이전 버전에서는'bpos1, bposy, _, _ = boid1'과 같은 네 개의 요소가있는 것처럼 'boid1'에 값이있을 것 인만큼'_'s을 추가합니다. 당연히 실제 이름을 사용할 수는 있지만 사용하지 않으면 '_'의도적임을 분명히합니다. –

답변

4

이러한 조건 중 어느 것도 맞지 않으면 어떻게됩니까?

if bposx < WALL: 
    new_speedDx = WALL_FORCE 
elif bposx > WIDTH - WALL: 
    new_speedDx = -WALL_FORCE 

... new_speedDx가 지정되어 있지 않음 때문에 그 값은 결정되지 않습니다.

당신은 new_speedDx이 경우에 있어야 무엇을 지정하여이를 완화 할 수

if bposx < WALL: 
    new_speedDx = WALL_FORCE 
elif bposx > WIDTH - WALL: 
    new_speedDx = -WALL_FORCE 
else: 
    new_speedDx = 0. 
5

폭보다 어느 쪽 벽보다도 더 bposx 것을 할 수 있어야한다 - WALL.

예 :

bposx = 10 
WALL = 9 
WIDTH = 200 

if bposx < WALL: # 10 is greater than 9, does not define new_speedDx 
    new_speedDx = WALL_FORCE 
elif bposx > WIDTH - WALL: # 10 is less than (200 - 9), does not define new_speedDx 
    new_speedDx = -WALL_FORCE 

가 합리적인 대체 값을 제시하기 어렵다 프로그램의 나머지 부분을 보지 않고,하지만 당신은 가능성이 같은 추가 할 :

else: 
    new_speedDx = 0 
+0

jsut가 추가되었으며 작동합니다! – user2089012

+1

좋습니다. 이미이 작업을 수행했을 수도 있지만 동일한 문제에 취약하기 때문에 new_speedDy에 대해 동일한 작업을 수행 할 수 있습니다. – uptownnickbrown

1

설명을

다른 사람들이 지적했듯이, 당신은 그 사건을 다루지 않고 있습니다. WALL <= pos <= WIDTH - WALL. 이 벽에 충돌하지 않는 경우

권장 변화는 아마도 boid 현재 속도로 계속됩니다. boid가 벽에 부딪치지 않으면 속도를 0으로 설정하는 코드가 있습니다. 이 솔루션은 기존 속도를 사용할 때 특유한 것입니다. 나는 그것이 당신의 상황에 중요하다고 생각합니다.

def new_speedD(boid1): 
    def new_speed(pos, velocity): 
     return WALL_FORCE if pos < WALL \ 
      else (-WALL_FORCE if pos > WIDTH - WALL \ 
      else velocity) 
    xpos, ypos, xvelocity, yvelocity = boid1 
    new_speedDx = new_speed(posx, xvelocity) 
    new_speedDy = new_speed(posy, yvelocity) 
    return new_speedDx, new_speedDy 

코드 일부는이 코드를 이해하기 어렵다 생각합니다. 벽
  • 그렇지 않으면, 여기에 반환 속도
  • general question on the ternary operator입니다 -

  • 그렇지 않으면, 반환 -WALL_FORCE POS> WIDTH 경우는 POS < 벽을 경우

    1. 반환 WALL_FORCE : 여기에 대한 간략한 설명입니다. 생각해라, 기억해라. "그것은 pythonistas에 의해 눈살을 찌푸리게되었다.

      이 코드를 사용하지 않는 경우

      ...

      원래로 돌아가서 yvelocity 경우에 오타를 수정 : bposx > WIDTH - WALL.yvelocityxpos에 종속되지 않습니다.

  • +0

    나는'if' 문을 삼항 연산자로 만드는 이점을 보지 못합니다. 단지 선을 너무 길어서 읽기가 어렵게 만듭니다. –

    +0

    @Lattyware : 글쎄, 한 가지 사실은 오리지널 코드에 오타가 있다는 것을 알아내는 것이 쉽지 않다. bposy = boid1 [1] if bposy WIDTH - WALL : new_speedDy = -WALL_FORCE' y-case에서 bposx에 대한 점검을 보시겠습니까? 한 줄짜리 삼항 연산자를 사용하여 x와 y에 대한 병렬 구조가 명백합니다. – hughdbrown

    +0

    그리고 한 줄에 모두 덤핑하면 더 쉽게 만들 수 있습니까? 나는 완전히 반대한다 - 그것들을 일렬로 세우는 것은 그것을 읽을 수없는 혼란으로 만든다. PEP-8은 선이 79자를 넘지 않아야한다고 제안합니다. –