Python编码风格

编写python代码的PEP8标准(http://www.python.org/dev/peps/pep-0008/)

  • 每个缩进层次使用4个空格。
  • 每行最多79个字符
  • 顶层的函数或类的定义之间空两行
  • 采用ASCII或UTF-8编码文件
  • 在文件顶端,注释和文档说明下面,每行每条import导入一个模块,同时按照标准库,第三方库和本地库导入顺序分组
  • 小括号,中括号,大括号,逗号之前没有额外空格
  • 类命名采用驼峰命名发

 

完了以后可以使用pep8来检查python文件是否符合PEP8标准。

1. python中的变量不需要先定义在使用,可以直接使用,重新使用可以付给不同类型的值。

2. 变量命名遵循C语言命名规则。

3. 大小写敏感。

4. 变量引用计数。

5. del语句可以直接释放资源,变量名删除,引用计数减一。

6. 变量内存自动管理回收,垃圾收集。

7. 指定编码在文件开头加入 #--coding:UTF-8-- 或者#coding=UTF-8

 

In [6]: a=12                    #无需定义,直接使用,python解释器根据右侧决定左侧类型

In [7]: print a
12

In [8]: id(a)                     #变量a在内存中的编码,
Out[8]: 25014352

In [9]: type(a)                 #变量a的类型
Out[9]: int

In [10]: b=12.33333

In [11]: id(b)                   #变量b在内存中所占用的内存编码
Out[11]: 25360264

In [12]: type(b)
Out[12]: float

In [13]: a="zhangsan"     #变量a重新指向一个新的字符串

In [14]: print a
zhangsan

In [15]: id(a)#变量a在内存中的编码为保存“zhangsan”的地方,原来a指向的内存编码里的内容并没有立即释放
Out[15]: 139844847653680

In [16]: type(a)
Out[16]: str     #变量a现在指向一个字符串
                                    

 python是动态类型语言,“引用”“对象”分离,如下几个python内置函数可以帮我我们理解python的内存存储:

id()    : 返回对象的内存地址

type()  : 返回对象的类型

is 关键字  : 用于判断两个引用所指的对象是否相同

sys.getrefcount()  :查看对象的引用计数

globals()  :查看词典

 

python缓存了整数和短字符串,因此每个对象只存了一份,长的字符串和其他字符串可以有多个相同的对象。

In [18]: a="zhangsan is beijing"

In [19]: b="zhangsan is beijing"

In [20]: print(a is b)
False

In [21]: a=[]

In [22]: b=[]

In [23]: print(a is b)
False

 在python中,每个对象都存有指向该对象的引用总数,即引用计数(reference count),当使用某个引用作为参数,传递给getrefcount()时,参数实际上创建了一个临时的引用,因此getrefcount()所得到的结果会比期望值多1.

In [25]: import sys

In [26]: 

In [26]: print(sys.getrefcount(a))
2

In [27]: 

In [27]: from sys import getrefcount

In [28]: 

In [28]: print(getrefcount(b))
2

 python的容器对象(container),例如表,词典等等的,可以包含多个对象,容器对象中包含的并不是元素对象本身,是指向各个元素对象的引用,对象应用对象。

引用减少

In [43]: a=1

In [44]: b=a

In [45]: print(getrefcount(b))
1558

In [46]: del a

In [47]: print(getrefcount(b))
1557

 del也可以删除容器中的元素

In [48]: x=[1,2,3]

In [49]: del x[0]

In [50]: print(x)
[2, 3]

 当某个引用指向对象A,当这个引用重新指向其他对象时,对象A的引用计数减少1个。

In [51]: y=[1,2,3]

In [52]: l=y

In [53]: print(getrefcount(l))
3

In [54]: y=7

In [55]: print(getrefcount(l))
2

 python的垃圾回收

简而言之,当python的某个对象引用计数将为0时,说明没有任何引用指向该对象,该对象就成为要被回收的垃圾了。然而垃圾回收时,python不能进行其他的任务了,频繁的垃圾回收将大大的降低python的工作效率,如果内存中的对象不多,就没有必要哦,python只会在特定条件下自动启动垃圾回收。当python运行时,会记录其中分配对象(object allocation)和取消对象(object deallocation)的次数,当两者的差值高于某个阀值时,垃圾回收会自动启动。

查看阀值:

In [56]: import gc

In [57]: print(gc.get_threshold())
(700, 10, 10)

 后面的两个10是分代回收相关的阀值,700是垃圾回收启动的阀值。可以通过set_threshold()重新设置阀值。

也可以手动启动垃圾回收gc.collect()

 

分代回收

python也有分代回收的策略(generation),这个策略的基本假设是存活时间越久的对象,我们的程序往往会产生大量的对象,许多对象很快产生和消失,但也有一些对象长期被使用。出于信任和效率,对于这样一些“长寿”对象,我们相信它们的用处,所以减少在垃圾回收中扫描它们的频率。

Python作为一种动态类型的语言,其对象和引用分离。这与曾经的面向过程语言有很大的区别。为了有效的释放内存,Python内置了垃圾回收的支持。Python采取了一种相对简单的垃圾回收机制,即引用计数,并因此需要解决孤立引用环的问题。Python与其它语言既有共通性,又有特别的地方。对该内存管理机制的理解,是提高Python性能的重要一步

 简单函数

1. def是定义函数的关键字。

2. 下面的x和y为形参,不需要类型修饰。

3. 函数的定义行需要“:”

4. 函数体整体缩进。

5. 函数可以拥有返回值,若无返回值,返回None,相当于C中的NULL。

def add(x,y):
	z=x+y
	return z
res=add(3,5)
print(res)

 局部变量和全局变量

局部变量的作用域覆盖全局变量(当局部变量定义了和全局变量一样的值的时候,全局变量就失效了。)

def p_num():
    num=5
    print num
num=10
p_num()
print(num)

结果为

5

10

函数内有局部变量定义,解释器不使用局部变量,局部变量的定义晚于被引用,就报错。(就是在编译阶段就出错了)

def p_num():
	print(num)
	num=5
	print(num)
num=10
p_num()
print(num)

 Traceback (most recent call last):
  File "/home/jiefy/work/2.py", line 6, in <module>
    p_num()
  File "/home/jiefy/work/2.py", line 2, in p_num
    print(num)
UnboundLocalError: local variable 'num' referenced before assignment

函数内部可以直接访问全局变量

def p_num():
	print(num)
num=10
p_num()
print(num)

10
10
[Finished in 0.1s]

函数内部修改全局变量,使用global关键字。

 

posted on 2017-09-14 16:39  心灯在林  阅读(156)  评论(0编辑  收藏  举报

导航