美文网首页
python笔记(七)变量

python笔记(七)变量

作者: 艺术家可达鸭 | 来源:发表于2018-12-15 19:17 被阅读2次

    变量/函数下划线的作用

    • value_:区分 Python 关键字,比如想要定义一个名为 class 的类,class_
    • _value:用来命名全局变量/函数,不会被from module import *,但是依旧可以被import module导入
    • __value:用来命名类变量/方法,防止被子类中同名成员覆盖,实际名字会变成_classname__value
    • __value__:魔术成员,最好不要去自定义这种风格的变量

    变量作用域

    1. Local:函数/方法/列表推导式/类
    2. Enclosing:外层函数/方法
    3. Global:模块
    4. Built-in:Python 的 builtins 模块。全局变量中有一个名为__builtins__的模块对象

    以 L –> E –> G –>B 的规则查找
    Python除了 def/class/lambda/列表推导式/类 外,其他如: if/elif/else/ try/except for/while 是没有名字空间的

    坑1:自由变量可访问不可赋值

    自由变量就是不在当前作用域中的变量

    变量的获取是按上述规则查找,但是对于变量的赋值(i=1 这种),只要该变量在当前作用域内没有被定义,就会定义一个新变量,除非使用 global,nonlocal 关键字

    global 关键字:不要定义新变量,使用全局的同名变量
    nonlocal 关键字:不要定义新变量,使用外层函数的同名变量
    globals():当前模块全部的全局变量
    locals():当前名字空间的所有变量,一般就是某个函数的全部变量

    def func():
        global tmp
        tmp=123
    # 如果全局变量存在,则将其赋值为 123
    # 如果全局变量不存在,则创建一个全局变量,并赋值为 123
    

    坑2:Enclosing 作用域

    Enclosing 是函数定义时的嵌套作用域,而不是函数调用时的。
    这其实不算是一个坑。我本身代码写得少,而我在 Java 中很少有【一个方法调用同一个类中的其它方法】的情况,所以对这种比较陌生。
    比如下面这段代码是错误的

    def say():
        print(s) # s 没有被定义,不能使用
    
    def main():
        s='hello'
        say()
    

    坑3:类的局部作用域

    类代码块是局部作用域,和方法的作用域是同级别的,不是嵌套的,所以以下代码是错误的

    class C():
        s=1
        def say(self):
            print(s) # s 没用被定义,必须使用 C.s
    

    坑4:类需要在定义完成后才能使用

    任何变量都要先定义后使用,这自不必说,但是以下情况常常使我忘记这点。

    class C():
        s=1
        ss=[ C.s + i for i in range(10) ] # 不能使用 C.s,因为类还没定义完,还没有 C 这个类
        ss=[ s + i for i in range(10) ] # 不能使用 s,因为列表推导式有自己的作用域
    

    坑5:UnboundLocalError

    下面的代码是错误的,i 已经在 Local 中被定义,所以不会去 Global 中查找,但是 Local 中 i 的使用先于定义,故报错。
    Java 中也有这个坑。

    i = 2
    def test():
        print(i)
        i = 1
    

    dir() 与 __dict__ 的区别

    __dict__:在当前实例中定义的成员,就是用self.value=value定义的成员。对于类就是类中定义的成员,对于函数方法,就是空,啥都没有
    dir():当前实例所有能访问到的成员,对于实例而言,它还能访问到它的类中的成员。类成员并不是类私有的,而是所有实例共享的
    dir() 获得的是包含属性名的列表;__dict__获得的是包含属性名和属性值的字典
    globals()和locals():类似于__dict__,只不过这两个是函数,而__dict__是属性

    魔术变量的访问顺序

    魔术变量如果不指定其所属的对象,那就是指 Global 中的魔术变量

    """
    module
    """
    
    def main():
        """
        main()
        """
        # __doc__='new module' 这一行将修改 Global 中的 __doc__ 属性
        print(__doc__, main.__doc__, __builtins__.__doc__, sep='\n')
    
    if __name__ == '__main__':
        main()
    

    相关文章

      网友评论

          本文标题:python笔记(七)变量

          本文链接:https://www.haomeiwen.com/subject/itaahqtx.html