美文网首页
Python 变量

Python 变量

作者: DebugWorld | 来源:发表于2020-04-29 18:39 被阅读0次

    呃...Python压根就没有变量的概念!更不需要声明变量!

    0X00、Java

    在C/C++/Java等静态语言中,变量是面向内存的,声明定义一个变量需要:

    • 表明空间大小(Java整型int的范围 -2147483648~2147483647)
    • 确定存储的类型(int、float、string等)
    • 只能声明一次
    // Java
    int a;            // 声明一个变量a,表明类型和范围(-2147483648~2147483647)
    a = 10;           // 给变量a赋值
    // int a = 10;    // 声明并初始化变量
    int a = 20;       // 会报错,变量a只能声明一次
    a = 10.0;         // 会报错,变量a只能指向int类型
    

    0X01、Python

    Python只有name(名字)和object(对象)的概念

    # python3
    a = 10       # 指向int类型
    a = 'test'   # 指向str类型,不会报错
    

    这个语句中a是一个name,10和 "test" 是object
    所有name在创建时必须关联到一个object

    name可以在创建以后指向任何一个object(包括不同类型)

    所以name本身没有类型,他关联的object是有类型的

    ps: Python的猴子补丁的实现就是基于name - object 机制

    a、Object

    Python所有的数据都用objec(对象)表示的,object在创建时有以下属性(参见手册章3)

    • 唯一id,不可改变,通过id(object)查看
    • 类型,不可改变,int、stri、list等
    • 值,根据类型形式分为mutable(可变),immutable(不可变)

    b、Name

    objec(对象)是用来使用的,比如参与表达式运算,或作为函数参数传递,Python并不直接使用object,而是使用name,这种间接的方式(参见手册9.1)

    • 将name关联到object,然后name就可以用在表达式
    • 一个object可以被多个name关联
    • name总是存在于特定的namespace中

    c、比喻说明

    直观比喻:

    • 对象,就像一个人,出生时就分配身份证ID,这个终身不变。
    • 人可以有不同的name(张伟,儿子,父亲,老公)但在特定情境下(namespace)都指的是同一个人。
    • 不同情境下(namespace),name可能指代不同人,比如河南的张伟和河北的张伟不是同一个人。

    代码说明:

    class A(object):
        a = 1
        b = 1
    class B(object):
        a = 'a'
       
    print(id(A().a))    # 4305226112
    print(id(A().b))    # 4305226112
    print(id(B().a))    # 4339756032
    """
    object 1和'test', 在python解释器中都有唯一id 4305226112、4339756032
    在特定namespace(class A)中,name(a和b)都指向object 1
    在不同namespace(class A, class B)中同一个name(a)指向不同object(1和'test')
    """
    d = 2
    print(id(d))      # 4305226144
    d = 3
    print(id(d))      # 4305226176
    """
    按照C/C++/Java语言特性,变量d的id应该是一样的
    但是在Python里却变了,这是因为d指向了不同的object(2和3)
    个人理解Python的name有点像c语言的指针,但又不是一回事
    """
    

    d、对象的可变与不可变

    • numbers(整数,浮点,布尔等)不可变,对!不可修改
    • list,dict之类的容器类对象,是可变对象

    容器实际存储的是object(对象)的reference(引用),a=list[0] 返回的是list的0位置reference关联的object的值,list[0]=4,实际是将list的0位置reference改成关联到4这个object,也就是说,Python压根就不能直接修改基础对象的值,只能修改容器中的renference

    e、Python数据模型的好处

    相比C/C++/Java语言,Python的数据模型显得很特别。它让编程者,更关注与数据对象的操作,而不是数据存储。这使得编程者能快速的实现想法,而不过多专注于存储细节。

    0X02、数据属性

    class Test(object):
        class_attribute = 0                 # 类属性,类和类的所有实例对象都可以访问到
    
        def __init__(self):
            # 下面这些都属于实例属性
            self.public_attribute = 10      # 前置单下划线,公有属性,
            self._attribute = 20            # 前置双下划线,(伪)私有属性,不能完全做到真正的私有,提醒使用者不要直接访问
            self.__attribute = 30           # 前置双下划线,私有化属性无法在外部直接访问, 需要通过 class name 访问
            self.__name__ = 40              # 前后双下划线,系统定义名字,__xxx__对Python 来说有特殊含义,对于普通的变量应当避免这种命名风格
            self.class_ = 50                # 后置单下划线,用于避免与Python关键词的冲突
    

    a、类属性

    class_attribute 这种属性是类属性,归Test类所有,虽然类的所有实例对象也都可以访问到,但是实例对象对类属性的操作,只能作用于该实例对象,不能作用于其他实例对象,但是类对类属性的操作,作用于所有类的实例对象。

    t1 = Test()
    t2 = Test()
    print(Test.class_attribute,
          t1.class_attribute,
          t2.class_attribute)
    # output 0 0 0
    Test.public_attribute2 = 1000       # 添加类属性
    t1.public_attribute3 = 10000        # t1添加类属性
    print(t1.public_attribute2, t2.public_attribute2)
    # output 1000 1000
    print(t2.public_attribute3)         # public_attribute3只在t1,t2会报错
    del Test.public_attribute2          # 删除类属性
    

    b、实例属性

    print(t1.public_attribute)          # 10
    print(t1._attribute)                # 20
    print(t1._Test__attribute)          # 30
    print(t1.__name__)                  # 40
    print(t1.class_)                    # 50
    

    0X03、参考

    Python3中文文档3.1

    Python3英文文档9.1

    相关文章

      网友评论

          本文标题:Python 变量

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