第3章 Python基础

Python语句中有一些基本规则和特殊字符

· 井号(#)表示之后的字符为Python注释
· 换行(\n)是标准的行分隔符(通常一个语句一行)
· 反斜线(\)是继续上一行
· 分号(;)将两个语句连接在一行中
· 冒号(:)将代码块的头和体分开

2、变量赋值

2.1 赋值操作符

Python语言中,等号(=)是主要的赋值操作符(其他的是增量赋值操作符)。

在Python语言中,对象是通过引用传递的。在赋值时,不管这个对象是新创建的,还是一个已经存在的,都是将该对象的引用(并不是值)赋值给变量。

>>> x = 1
>>> y = x = x + 1    # 链式赋值
>>> x, y
(2, 2)

Python不支持类似x++或--x这样的前置/后置自增/自减运算。

>>> x = y = z = 1  # 多重赋值
>>> x, y, z
(1, 1, 1)

将多个变量同时赋值的方法我们称为多元赋值(multuple)。采用这种方式赋值时,等号两边的对象都是元组。

>>> x, y, z = 1, 2, 'a string'  # (x, y, z) = (1, 2, 'a string')
>>> x, y, z
(1, 2, 'a string')
>>> x, y = y, x      # 直接交换两个变量的值
>>> x, y
(2, 1)

3、标识符

3.1 合法的Python标识符

· 第一个字符必须是字母或下划线(_)
· 剩下的字符可以是字母和数字或下划线
· 大小写敏感

 3.2 专用下划线标识符

Python用下划线作为变量前缀和后缀指定特殊变量。

· _xxx_ 系统定义名字
· _xxx 类中的私有变量名

一般来讲,变量名_xxx被看作是“私有的”,在模块或类外不可以使用。当变量是私有的时候,用_xxx来表示变量是很好的习惯。

3.3 模块结构和布局

下面是一种较为合理的模块布局:

# (1)起始行
# (2)模块文档
# (3)模块导入
# (4)变量定义
# (5)类定义
# (6)函数定义
# (7)主程序
class Test():
    '''测试类'''

    def test01(self):
        '''测试函数'''
        pass

if __name__ == "__main__":
    print(Test().__doc__)           # 获取类的文档信息:测试类
    print(Test().test01.__doc__)    # 获取函数的文档信息:测试函数
    print(Test().test01.__name__)   # 获取函数的方法名:test01
    print(__file__)                 # 获取模块的路径:E:/Temp/test_register.py
class FooClass():
    pass

if __name__ == "__main__":
    foo = FooClass()

· 如果模块是被导入,__name__的值为模块的名字;
· 如果模块是被直接执行,__name__的值为'__main__'

3.5 内存管理

· 变量无需事先声明;
· 变量无需指定类型;
· 不用关心内存管理;
· 变量名会被“回收”;
· del语句能够直接释放资源。

3.5.1 动态类型

在Python中,对象的类型和内存占用都是运行时确定的。

在创建——也就是赋值时,解释器会根据语法和右侧的操作数来决定新对象的类型。在对象创建后,一个该对象的应用会被赋值给左侧的变量。

 

 3.5.2 引用计数器

Python内部记录着所有使用中的对象各有多少引用。

一个内部跟踪变量,称为一个引用计数器。每个对象各有多少个引用,简称引用计数。

当对象被创建时,就创建一个引用计数,当这个对象不再需要时,也就是说,这个对象的引用计数变为0时,它被垃圾回收。

 3.5.3 增加引用计数

当对象被创建并(将其引用)赋值给变量时,该对象的引用计数就设置为1。

当同一个对象(的引用)又被赋值给其它变量时,或作为参数传递给函数、方法或类实例时,或者被赋值为一个窗口对象的成员时,

该对象的一个新的引用,或者称作别名。就被创建(则该对象的引用计数自动加1)。

如下:

x = 3.14   # 创建了一个浮点型对象并将其引用赋值给x。x是第一个引用,因此该对象的引用计数被设置为1。
y = x      # 创建了一个指向同一对象的别名y。并没有为y创建一个新对象。而是该对象的引用计数增加了1(变成了2).

总之,对象的引用计数增加时:

· 对象被创建
  x = 3.14
· 或另外的别名被创建
  y = x
· 或被作为参数传递给函数
  foobar(x)
· 或成为容器对象的一个元素
  myList = [123, x, 'xyz']

3.5.4 减少引用计数

当对象的引用被销毁时,引用计数会被减少。

如当引用离开其作用范围时,常出现在函数运行结束时,所有局部变量都被自动销毁,对象的引用计数也就随之减少。

foo = 'xyz'    # 引用计数是1
bar = foo      # 增加了别名bar,引用计数变为2
foo = 123     # foo被重新赋值,xyz对象的引用计数自动减1,重新变成了1

总之,一个对象的引用计数在以下情况会减少:

· 一个本地引用离开了其作用范围,比如foobar()函数结束时;
· 对象的别名被显示销毁;
  del y    # or del x
· 对象的一个别名被赋值给其他对象;
  x = 123
· 对象被从一个窗口对象中异常;
  myList.remove(x)
· 窗口对象本身被销毁;
  del myList    

 del语句

Del语句会删除对象的一个引用,它的语法如下:

del obj1[, obj2[, ...objN]]

例如,在上例中执行del y会产生两个结果:

· 从现在的名称空间中删除y
· x的引用计数减1

# 执行del x会删除该对象的最后一个引用,也就是该对象的引用计数会被减为0,导致该对象从此“无法访问”或“无法抵达”,该对象就成为垃圾回收机制的回收对象。

3.5.5 垃圾收集

不再使用的内存会被一种称为垃圾收集的机制释放。

垃圾收集器是一块独立代码,它用来寻找引用计数为0的对象。它也负责检查哪些虽然引用计数大于0但也应该被销毁的对象。

Python的垃圾收集器实际上是一个引用计数器和一个循环垃圾收集器。当一个对象的引用计数变为0,解释器会暂停,释放掉这个对象和仅有这个对象可访问的其他对象。

作为引用计数的补充,垃圾收集器也会留心被分配的总量很大的(以及未通过引用计数销毁的那些)对象。在这种情况下,解释器会暂停下来,试图清理所有未引用的循环。

 

import os

while True:
    file = input("请输入文本名:")
    fileName = file + r'.txt'            # 此处的fileName是全局变量
    if os.path.exists(fileName):     # 判断该文件名是否已存在
        print("文件《" + fileName + "》已存在!")
    else:
        break

with open(fileName, 'a') as f:
    while True:
        entry = input(">")
        if entry == 'esc':
            break
        else:
            f.write(entry)

 

posted @ 2021-08-15 10:27  Maruying  阅读(58)  评论(0编辑  收藏  举报