>  Q&A  >  본문

Python 변수의 범위 정보

다음과 같은 기능이 있습니다:

으아악

호출 후 문제가 발생하지 않았습니다. 출력:
140560473157960
140560473157960
140560473157960
[1, 2, 3]

그러나 다음과 같이 내부의 x를 문자열로 바꿉니다.

으아악

다시 전화를 걸면 다음과 같이 됩니다:

으아악

给我你的怀抱给我你的怀抱2712일 전705

모든 응답(3)나는 대답할 것이다

  • 我想大声告诉你

    我想大声告诉你2017-05-18 10:55:10

    쉬운 것부터 어려운 것까지 하나씩 답변해 드립니다. 제 소견이므로 누군가가 제가 말한 내용이 틀렸다고 보면 지적해 주셨으면 좋겠습니다.
    C의 포인터와 비슷합니다: 맞습니다. py< /code>에서는 거의 모든 것이 객체입니다. 변수를 할당하더라도 먼저 객체를 생성한 다음 변수가 이 를 가리키도록 해야 합니다. object 이며, 개체도 변경 가능한 개체변경 불가능한 개체로 구분됩니다. 변경 가능한 개체에 대해 작업을 수행하면 다른 개체에 영향을 미칩니다. 이 개체를 가리키는 변수입니다. 예: py里面, 几乎所有的事物都是对象, 就连变量赋值, 也是先生成对象, 再让变量指向这个对象,而对象还分可变对象不可变对象, 在对可变对象操作时, 是会影响到其他指向这个对象的变量, 例如:

    o = [1, 2, 3, 4]
    b = o
    print id(o)
    print id(b)
    b[1] = 123123
    print b
    print o
    输出:
    39946376
    39946376
    [1, 123123, 3, 4]
    [1, 123123, 3, 4]  # o指向的列表也被改变

    而对于不可变对象, 是直接就放弃旧的对象, 而指向新的对象, 例如:

    s = '123123'
    print id(s)
    s = '32131'
    print id(s)
    
    
    # 输出:
    41392768
    41392808
    

    所以你在操作python对象时, 需要谨记该对象是属于哪种类型, 你的操作又会不会因为这些特性而失败或者没达到自己想要的效果.

    未定义的变量: python在查找变量时, 将遵循LEGB的顺序, 只有都查找完毕还是没找到的情况下, 才会触发NameError异常, 这个可以参考我的一篇博文: Python: 作用域(scope) 和 LEGB

    UnboundLocalError: 这个问题是最常见, 也是最难解释的, 因为我们总是相当然地觉得, 它必定就会根据ELGB的顺序去查到变量;其实我们的理解并没错误, 只是我们忽略了一点:赋值语句 으아아아

    불변 객체의 경우 이전 객체는 바로 폐기되고 새 객체를 가리킵니다. 예: 🎜 으아아아 🎜그래서 Python 객체를 조작할 때는 객체가 어떤 유형에 속해 있는지, 이러한 특성으로 인해 조작이 실패할지, 아니면 원하는 효과를 얻지 못할지 염두에 두어야 합니다.🎜 🎜🎜정의되지 않은 변수🎜: Python이 변수를 검색할 때 LEGB의 순서를 따릅니다. 검색이 완료되거나 찾을 수 없는 경우에만 NameError 예외가 발생합니다. 내 블로그 게시물: Python: Scope 및 LEGB🎜 🎜🎜UnboundLocalError🎜: 이 문제는 가장 일반적이고 설명하기 가장 어렵습니다. 왜냐하면 우리는 ELGB의 순서에 따라 변수를 찾을 것이라고 항상 당연하게 여기기 때문입니다. 사실 우리의 이해는 잘못된 것이 아니라 단지 무시한다는 점 한가지 : 대입문, 함수 코드 세그먼트에 대입문이 없으면 이런 문제는 발생하지 않는데 대입문이 나타날 때 왜 오류가 발생하는 걸까요? 위에서 언급한 것처럼 Python 범위와 관련하여 Python 범위가 동적이 아니라 정적이라고 언급한 기사는 스크립트 파일의 들여쓰기에서 볼 수 있으므로 코드에서 다음과 같습니다. 🎜으아악

    In inside中, 已经有了赋值语句, 所以对于x,他已经不会从enclosing 或者global甚至bulitin里面去查找, 它已经被认定在local域了, 只是这个值并没有和真正的对象'inside'建立起绑定关系, 因为代码没有运行到真正的赋值语句, 所以, 会触发这个UnboundLocalError. 而为什么那个列表会可以那样做, 因为他们两个是完全不同的操作, 同样都是print(id(x))list的操作字节码是LOAD_DEREF, 而字符串的操作字节码是LOAD_FAST, 而x[:]=[1,2,3]/x='inside'分别对应的字节码又是STORE_SLICE+3STORE_FAST, 前者是在原来的基础上修改, 而后者是重新指向新的对象, 而这两种方式的区别, 决定了,它们在构建函数时, 以怎样的形式存放x, 这个就涉及到python函数构建的原理了, 有兴趣可以看看源码中的object/ceval.c源码, 这是虚拟机运行的原理, 关于这个问题可以简单看我另一篇文章, 比较简单将UnboundLocalError: 마법의 UnboundLocalError: 할당 전에 참조된 로컬 변수 x에 대해 이야기해 보겠습니다

    회신하다
    0
  • 某草草

    某草草2017-05-18 10:55:10

    내부 함수에서 새 변수 x를 다시 할당했는데 두 x의 범위가 다릅니다.
    UnboundLocalError는 내부 범위에서 초기화되지 않은 변수를 인쇄했기 때문에 발생합니다.
    자세한 내용은 다음 설명을 참조하세요:
    https://docs.python.org/2/faq...

    회신하다
    0
  • PHP中文网

    PHP中文网2017-05-18 10:55:10

    기본적으로 Lin_R은 이를 매우 명확하게 설명했습니다.
    외부 기능과 내부 기능의 영역은 다릅니다. inside 함수에서 x에 값을 할당했기 때문에 변수 x가 inside 함수에서 사용되면 x는 inside의 로컬 도메인에 있는 것으로 간주됩니다. 이때 x는 다른 필드의 값을 사용하지 않습니다. 그래서 인쇄(x)할 때 x에는 초기화된 값이 없기 때문에 오류가 발생합니다. C에서는 정의되었지만 할당되지 않은 변수를 사용할 수 있지만 Python에서는 이를 허용하지 않습니다.

    python3에는 이 문제를 해결하기 위한 nonlocal 문이 있습니다.

    으아악

    글로벌 도메인에 x 변수가 없기 때문에 현재 global 문을 사용할 수 없다는 점에 유의하세요.

    회신하다
    0
  • 취소회신하다