zoukankan      html  css  js  c++  java
  • Python学习笔记:有关<Python3学习笔记>学习整理,第2章类型[1]

    2.1.1 印象

    我们习惯将生物分为动物,植物,进而又有猫科,犬科等细分,通过对个体的研究,归纳其共同特征,抽象成便于描述的种族模版,有了模版后,可据此创建大量行为类似的个体,所以,分类是个基础工程。

    在专业术语上,我们将族群或类别乘坐类型(class),将个体叫做实例(instance)。类型持有同族个体的共同行为和共享状态,而实例仅保存私有特性即可。如此,在内存空间布局上才是最高效的。

    每个实例都持有所属类型的指针。需要时,通过它间接访问目标即可。但从外在逻辑接口看,任何实例都是“完整”的

    存活实例对象都有“唯一”id值:

    补充:

    id()函数:用于获取对象的内存地址

    语法:id([object])

    返回值:返回对象的内存地址。

    可用type返回实例所属的类型:

    要判断实例是否属于特定类型,可以使用isinstance函数

    补充:

    isinstance()函数:判断一个对象是否是一个已知类型

    语法:isinstance(object, classinfo)

    参数:

    object -- 实例对象。
    classinfo -- 可以是直接或间接类名、基本类型或者由它们组成的元组。

    返回值:如果对象的类型与参数二的类型(classinfo)相同则返回 True,否则返回 False。

    isinstance() 与 type() 区别:
    type() 不会认为子类是一种父类类型,不考虑继承关系。
    isinstance() 会认为子类是一种父类类型,考虑继承关系。
    如果要判断两个类型是否相同推荐使用 isinstance()

    任何类型都是其祖先类型的子类,同样,对象也可以被判定为其祖先类型的实例

    class A:
        pass
    class B(A):
        pass
    print(issubclass(B,A))

    结果:

    补充:

    issubclass():用于判断参数class是否是类型参数classinfo的子类

    语法:issubclass(class, classinfo)

    参数:

    class -- 类
    classinfo -- 类

    返回值:如果 class 是 classinfo 的子类返回 True,否则返回 False

    注意:所有类型都有一个共同的祖先类型object,它为所有类型提供原始模版,以及系统所需的基本操作方式

    class A:
        pass
    class B(A):
        pass
    print(issubclass(B,object))

    结果:

    类型虽然是抽象族群概念,但在实现上也只是个普通的对象实例,区别在于,所有类型都是由type创建,这和继承没有关系

    单就类型对象而言,其本质就是用存储方法和字段成员的特殊容器,用同一份涉及来实现才是正常思路,当然,类型对象属于创建者这样的特殊存在,默认情况下,它们由解释器在首次载入时自动生成,生命周期与进程相同,且仅有一个实例

    2.1.2 名字

    在通常认知里,变量是一段具有特定格式的内存,变量名则是内存别名,因为在编码截断,无法确定内存的具体位置,故使用名称符号代替

    静态编译和动态解释型语言对于变量名字处理方式的不同点:

    静态编译:静态编译器或链接器会以固定地址,或直接、间接寻址指令代替变量名,也就是说,变量名不参与执行过程,可被剔除。

    动态解释型语言:名字和变量通常是两个运行期实体。名字不但有自己的类型,还需要分配内存,并介入执行过程。甚至可以说,名字才是动态模型的基础

    名字必须要与目标对象关联起来才有意义,最直接的关联操作就是负值,而后对名字的引用都被解释为对目标对象进行操作

    赋值步骤:

    1.准备好右值目标对象

    2.准备好名字

    3.在名字空间里为两者建立关联(namespace{名字:目标对象})

    即便如此,名字与目标对象也仅是引用关联,名字只负责招人,但对此人一无所知。鉴于在运行期才能知道名字引用的目标类型,所以说Python是一种动态类型语言

    名字空间:

    名字空间(namespace):是专门用来存储名字和目标引用关联的容器

    对Python而言,每个模块(源码文件)都有一个全局名字空间。而根据代码作用域,又有当前名字控件或本地名字空间一说,如果直接在模块级别执行,那么当前名字空间和全局名字空间相同,但在函数内,当前名字空间就专指函数作用域

    名字空间默认使用字典数据结构,由多个键值对组成

    内置函数globals和locals分别返回全局名字空间和本地名字空间字典

    代码1:

    y=100
    print(id(globals()))
    print(id(locals()))
    print(globals())
    print(locals())

    结果1:

    30466768
    30466768
    {'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x00000000003A1CC0>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': 'D:/Pyexerice/func_lambda1.py', '__cached__': None, 'y': 100}
    {'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x00000000003A1CC0>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': 'D:/Pyexerice/func_lambda1.py', '__cached__': None, 'y': 100}

    此时globals和locals指向相同,所以内存地址相同,结果相同

    代码2:

    def test():
        y = 100
        print(id(globals()))
        print(id(locals()))
        print(globals())
        print(locals())
    test()

    结果2:

    30663376
    39180904
    {'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x0000000001CF1CC0>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': 'D:/Pyexerice/func_lambda1.py', '__cached__': None, 'test': <function test at 0x0000000001D2C1E0>}
    {'y': 100}

    可以看到,此时globals和locals的内存地址不同,由此可见,globals总是指向模块名字空间,而locals则是指向当前作用域环境

    未完待续

  • 相关阅读:
    Maven介绍及安装与配置
    Xshell使用技巧总结
    UML类图
    vim使用案例
    Linux常用命令3(压缩和解压缩总结)
    Linux常用命令2(远程文件下载+查看文件内容)
    Linux常用命令1
    JOptionPane类提示框常用方法总结
    HTTP基础知识3
    HTTP基础知识2
  • 原文地址:https://www.cnblogs.com/reseelei-despair/p/11127627.html
Copyright © 2011-2022 走看看