十分钟学习Python的进阶语法

2017-01-13 10:52:26来源:csdn作者:u010700335人点击

第七城市

(0)目录


VMware
下安装Ubuntu的吐血经历



零基础学习Shell编程



Linux下的makefile的妙用



Linux调试神器
-- gdb



十分钟学会Python的基本类型


分布式版本管理神器--GIT





GIT文件的三种状态
& Git SSH秘钥问题



十分钟学习Python的进阶语法



配置SSH无密码访问及Linux热键、重启、kill进程



Java的不定长参数和Python的不定长参数对比

一:起因


(1)作为胶水语言的Python,可谓无处不在,快速开发原型网站;大数据处理等领域应用甚广


(2)学过c/c++ 或者 Java的ITers 很容易学习Python,特别是对于上手入门级的Python语法


(3)刚刚开始学习Python,练习Python时,可能感觉特别别扭 —— 完全没有方法{} ,近几年靠:和严格的缩进来进行代码段,程序段的分隔


(4)一些Python源代码的分享,请下载


二:Python 进阶语言


(1)python中%r和%s的区别——%r用rper()方法处理对象 —— %s用str()方法处理对象


有些情况下,两者处理的结果是一样的,比如说处理int型对象:

text = "I am %d years old." % 22
print "I said: %s." % text
print "I said: %r." % text
I said: I am 22 years old..
I said: 'I am 22 years old.'. // %r 给字符串加了单引号(2)Python中if __name__ == '__main__':作用
#hello.py
def sayHello():
str="hello"
print(str);if __name__ == "__main__":
print ('This is main of module "hello.py"')
sayHello()python作为一种脚本语言,用python写的各个module都可以包含以上那么一个类似c中的main函数,只不过python中的这种__main__与c中有一些区别,主要体现在:

1)当单独执行该module时,比如单独执行以上hello.py: python hello.py,则输出This is main of module "hello.py"hello可以理解为"if __name__=="__main__":" 这一句与c中的main()函数所表述的是一致的,即作为入口;


2)当该module被其它module 引入使用时,其中的"if __name__=="__main__":"所表示的Block不会被执行,这是因为此时module被其它module引用时,其__name__的值将发生变化,__name__的值将会是module的名字。比如在python shell中import hello后,查看hello.__name__:>>> import hello>>> hello.__name__'hello'>>>


3)因此,在python中,当一个module作为整体被执行时,moduel.__name__的值将是"__main__";而当一个module被其它module引用时,module.__name__将是module自己的名字,当然一个module被其它module引用时,其本身并不需要一个可执行的入口main了

if __name__ == '__main__':
print 'This program is being run by itself'
else:
print 'I am being imported from another module'

(3)我自己的疑问:我能明白面向对象编程的概念,感觉python用模块就能解决,为啥还要有class之类的东西?


1)先回答__:由于python的类成员都是公有、公开的被存取public,缺少像正统面向对象语言的私有private属性,于是就用__来将就一下,模拟私有属性。这些__属性往往是内部使用,通常情况下不用改写。也不用读取。加上2个下划线的目的,一是不和普通公有属性重名冲突,二是不让对象的使用者(非开发者)随意使用。


2)面向对象是一种方法学的提高,不用对象用模块的确能行,就像C语言也用类似的、没有对象的方式提供模块,也能开发任何东西。但用了对象能提高代码复用、提高开发效率,减轻开发者的劳动。简单说,面向对象就类似于工厂做一个石膏雕塑:


class类就相当于模具,object对象相当于模具倒出来的雕塑,雕塑可以大量被复制。要修改雕塑,是去修改模具,而不是改雕塑成品。


从数据的角度,一个雕塑可能由多个基础部件组成,手、脚、头,这些是数据,当然对象也有动作,对象所有的函数都是它的动作,比如跑、吃、叫。


最常见的,学生类,规定一些数据,姓名、电话、年龄、这些是数据,学生会“答题” “吃饭”,“消费”,“联系”“动手”这些是传递消息的动作。


这种把数据和动作结合就是一个对象,类拿来规范这些数据和动作。再次使用这同一类的对象,就不需要重复开发。


(4)Python中__init__(初始化操作) 和 __del__(结束操作,如文件的关闭和数据库的关闭等)的作用:


1)Python中没有专用的构造和析构函数,但是一般可以在__init__和__del__分别完成初始化和删除操作,可用这个替代构造和析构。还有一个__new__用来定制类的创建过程,不过需要一定的配置,此处不做讨论。


2)类的成员函数默认都相当于是public的,但是默认开头为__的为私有变量,虽然是私有,但是我们还可以通过一定的手段访问到,即Python不存在真正的私有变量。如:由于Python的特殊性,全局成员变量是共享的,所以类的实例不会为它专门分配内容空间,类似于static,具体使用参看下面的例子。

测试1:
# encoding:utf8class NewClass(object):
num_count = 0 # 所有的实例都共享此变量,即不单独为每个实例分配
def __init__(self,name):
self.name = name
NewClass.num_count += 1
print name,NewClass.num_count
def __del__(self):
NewClass.num_count -= 1
print "Del",self.name,NewClass.num_count
def test():
print "aa"
aa = NewClass("Hello")
bb = NewClass("World")
cc = NewClass("aaaa")
print "Over"Hello 1
World 2
aaaa 3
OverDeException l Hello 2
AttributeError: "'NoneType' object has no attribute 'num_count'" in <bound method NewClass.__del__ of <__main__.NewClass object at 0x01AF18D0>> ignored
Exception AttributeError: "'NoneType' object has no attribute 'num_count'" in <bound method NewClass.__del__ of <__main__.NewClass object at 0x01AF1970>> ignored我们发现,num_count 是全局的,当每创建一个实例,__init__()被调用,num_count 的值增一,当程序结束后,所有的实例会被析构,即调用__del__() 但是此时引发了异常。查看异常为 “NoneType” 即 析构时NewClass 已经被垃圾回收,所以会产生这样的异常。

但是,疑问来了?为什么会这样?按照C/C++等语言的经验,不应该这样啊!经过查找资料,发现:Python的垃圾回收过程与常用语言的不一样,Python按照字典顺序进行垃圾回收,而不是按照创建顺序进行。所以当系统进行回收资源时,会按照类名A-Za-z的顺序,依次进行,我们无法掌控这里的流程。


SO,继续查找,我们还可以通过self.__class__访问到类本身,然后再访问自身的共享成员变量,即 self.__class__.num_count , 将类中的NewClass.num_count替换为self.__class__.num_count 编译运行,如下:

# encoding:utf8class NewClass(object):
num_count = 0 # 所有的实例都共享此变量,即不单独为每个实例分配
def __init__(self,name):
self.name = name
self.__class__.num_count += 1
print name,NewClass.num_count
def __del__(self):
self.__class__.num_count -= 1
print "Del",self.name,self.__class__.num_count
def test():
print "aa"aa = NewClass("Hello")
bb = NewClass("World")
cc = NewClass("aaaa")print "Over"
Perfect!我们完美地处理了这个问题!(5)python中的全局变量和局部变量

函数内部的和函数外部的不共享一个变量,特别是出现 = (等号)时;但是同一个函数内的不同代码块之间可以共享一个变量详见


(6)Python高效读写文件


1)写入多行 ——file_object.writelines(list_of_text_strings)


注意,调用writelines写入多行在性能上会比使用write一次性写入要高。


2)在处理日志文件的时候,常常会遇到这样的情况:日志文件巨大,不可能一次性把整个文件读入到内存中进行处理,例如需要在一台物理内存为 2GB 的机器上处理一个 2GB 的日志文件,我们可能希望每次只处理其中 200MB 的内容。


在 Python 中,内置的 File 对象直接提供了一个 readlines(sizehint) 函数来完成这样的事情。以下面的代码为例:


file = open('test.log', 'r')
sizehint = 209715200 # 200M
position = 0
lines = file.readlines(sizehint)
while not file.tell() - position < 0:
position = file.tell()#Python文件操作tell()方法:这种方法简单地返回文件的当前位置读/写指针在文件。
lines = file.readlines(sizehint)

每次调用 readlines(sizehint) 函数,会返回大约 200MB 的数据,而且所返回的必然都是完整的行数据,大多数情况下,返回的数据的字节数会稍微比 sizehint 指定的值大一点(除最后一次调用 readlines(sizehint) 函数的时候)。通常情况下,Python 会自动将用户指定的 sizehint 的值调整成内部缓存大小的整数倍。


(7)Python 的文件读取方式


Python提供了基本的函数和必要在默认情况下对文件进行操作的方法。可以使用一个文件对象file来做大部分文件操作。open 函数:想要读取或写入文件,必须使用Python内置的open()函数来打开它。该函数创建一个文件对象,这将用来调用与之关联的其他支持方式:


语法:file object = open(file_name [, access_mode][, buffering])


1)参数的详细信息:


file_name: file_name参数是一个字符串值,包含您要访问的文件的名称。


access_mode: access_mode决定了文件必须被打开,即,读,写,追加等的可能值是下表中给定的一个完整的列表的模式。这是可选参数,默认文件存取方式为read (r)。


buffering: 如果缓冲值被设置为0时,没有缓冲将发生。如果该缓冲值是1,行缓冲会在访问一个文件来执行。如果指定的缓冲值为大于1的整数,则缓冲作用将与所指示的缓冲区的大小进行。如果为负,则缓冲区的大小是系统默认(默认行为)。


2)模式 描述


r 打开一个文件为只读。文件指针置于该文件的开头。这是默认模式。rb 打开一个文件只能以二进制格式读取。文件指针置于该文件的开头。这是默认模式。r+ 打开用于读取和写入文件。文件指针将会在文件的开头。rb+ 打开用于读取和写入二进制格式的文件。文件指针将会在文件的开头。w 打开一个文件只写。覆盖该文件,如果该文件存在。如果该文件不存在,则创建用于写入一个新的文件。wb 打开一个文件只能以二进制格式写入。覆盖该文件,如果该文件存在。如果该文件不存在,则创建用于写入一个新的文件。w+ 打开用于写入和读取的文件。覆盖现有的文件,如果文件存在。如果该文件不存在,则创建读取和写入新的文件。wb+ 打开用于写入和读取的二进制格式的文件。覆盖现有的文件,如果文件存在。如果该文件不存在,则创建读取和写入新的文件。a 将打开追加文件。文件指针是在文件的结尾。也就是说,该文件是在附加模式。如果该文件不存在,它创造了写入一个新的文件。ab 将打开追加的二进制格式的文件。文件指针在该文件的结束。也就是说,该文件为追加模式。如果该文件不存在,它创建并写入一个新的文件。a+ 打开为追加和读取文件。文件指针在该文件的结束。该文件将为追加模式。如果该文件不存在,它创建并读取和写入的新文件。ab+ 打开两个追加和读取的二进制格式的文件。文件指针在该文件的结束。该文件将在追加模式。如果该文件不存在,它创建并读取和写入的新文件。


3)文件操作:


os.mknod("test.txt")创建空文件fp = open("test.txt","w+") 直接打开一个文件,如果文件不存在则创建文件fp.read([size]) #size为读取的长度,以byte为单位fp.readline([size]) #读一行,如果定义了size,有可能返回的只是一行的一部分fp.readlines([size])#把文件每一行作为一个list的一个成员,并返回这个list。其实它的内部是通过循环调用readline()来实现的。如果提供size参数,size是表示读取内容的总长,也就是说可能只读到文件的一部分。fp.write(str) #把str写到文件中,write()并不会在str后加上一个换行符fp.writelines(seq)#把seq的内容全部写到文件中(多行一次性写入)。这个函数也只是忠实地写入,不会在每行后面加上任何东西。fp.close()#关闭文件。python会在一个文件不用后自动关闭文件,不过这一功能没有保证,最好还是养成自己关闭的习惯。 如果一个文件在关闭后还对其进行操作会产生ValueErrorfp.flush() #把缓冲区的内容写入硬盘fp.fileno() #返回一个长整型的”文件标签“fp.isatty() #文件是否是一个终端设备文件(unix系统中的)fp.tell() #返回文件操作标记的当前位置,以文件的开头为原点fp.next()#返回下一行,并将文件操作标记位移到下一行。把一个file用于for … in file这样的语句时,就是调用next()函数来实现遍历的。fp.seek(offset[,whence]) #将文件打操作标记移到offset的位置。这个offset一般是相对于文件的开头来计算的,一般为正数。但如果提供了whence参数就不一定了,whence可以为0表示从头开始计算,1表示以当前位置为原点计算。2表示以文件末尾为原点进行计算。需要注意,如果文件以a或a+的模式打开,每次进行写操作时,文件操作标记会自动返回到文件末尾。fp.truncate([size])#把文件裁成规定的大小,默认的是裁到当前文件操作标记的位置。如果size比文件的大小还要大,依据系统的不同可能是不改变文件,也可能是用0把文件补到相应的大小,也可能是以一些随机的内容加上去。


(8)目录操作:


os.mkdir("file")创建目录复制文件:shutil.copyfile("oldfile","newfile")oldfile和newfile都只能是文件shutil.copy("oldfile","newfile")oldfile只能是文件夹,newfile可以是文件,也可以是目标目录复制文件夹:shutil.copytree("olddir","newdir")olddir和newdir都只能是目录,且newdir必须不存在重命名文件(目录)os.rename("oldname","newname")文件或目录都是使用这条命令移动文件(目录)shutil.move("oldpos","newpos") 删除文件os.remove("file")删除目录os.rmdir("dir")只能删除空目录shutil.rmtree("dir")空目录、有内容的目录都可以删转换目录os.chdir("path")换路径2)将文件夹下所有图片名称加上'_fc'python代码:


# -*- coding:utf-8 -*-
import re
import os
import time
#str.split(string)分割字符串
#'连接符'.join(list) 将列表组成字符串
def change_name(path):
global i
if not os.path.isdir(path) and not os.path.isfile(path):
return False
if os.path.isfile(path):
file_path = os.path.split(path) #分割出目录与文件
lists = file_path[1].split('.') #分割出文件与文件扩展名
file_ext = lists[-1] #取出后缀名(列表切片操作)
img_ext = ['bmp','jpeg','gif','psd','png','jpg']
if file_ext in img_ext:
os.rename(path,file_path[0]+'/'+lists[0]+'_fc.'+file_ext)
i+=1 #注意这里的i是一个陷阱
#或者
#img_ext = 'bmp|jpeg|gif|psd|png|jpg'
#if file_ext in img_ext:
#print('ok---'+file_ext)
elif os.path.isdir(path):
for x in os.listdir(path):
change_name(os.path.join(path,x)) #os.path.join()在路径处理上很有用
第七城市

最新文章

123

最新摄影

微信扫一扫

第七城市微信公众平台