⼗分钟学习Python的进阶语法
(0)⽬录
⼀:起因
(1)作为胶⽔语⾔的Python,可谓⽆处不在,快速开发原型⽹站;⼤数据处理等领域应⽤甚⼴
(2)学过c/c++ 或者 Java的ITers 很容易学习Python,特别是对于上⼿⼊门级的Python语法
(3)刚刚开始学习Python,练习Python时,可能感觉特别别扭 —— 完全没有⽅法{} ,近⼏年靠:和严格的缩进来进⾏代码段,程序段的分隔
(4)
⼆: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:utf8
class 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
Over
DeException 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>
我们发现,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:utf8
class 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 = adlines(sizehint)
while ll() - position < 0:
position = ll()#Python⽂件操作tell()⽅法:这种⽅法简单地返回⽂件的当前位置读/写指针在⽂件。
lines = adlines(sizehint)
每次调⽤ readlines(sizehint) 函数,会返回⼤约 200MB 的数据,⽽且所返回的必然都是完整的⾏数据,⼤多数情况下,返回的数据的字节数会稍微⽐ sizehint 指定的值⼤⼀点(除最后⼀次调⽤ readlin
es(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("") 创建空⽂件
fp = open("","w+") 直接打开⼀个⽂件,如果⽂件不存在则创建⽂件
fp.write(str) #把str写到⽂件中,write()并不会在str后加上⼀个换⾏符
fp.writelines(seq) #把seq的内容全部写到⽂件中(多⾏⼀次性写⼊)。这个函数也只是忠实地写⼊,不会在每⾏后⾯加上任何东西。
fp.close() #关闭⽂件。python会在⼀个⽂件不⽤后⾃动关闭⽂件,不过这⼀功能没有保证,最好还是养成⾃⼰关闭的习惯。 如果⼀个⽂件在关闭后还对其进⾏操作会产⽣ValueError
fp.flush() #把缓冲区的内容写⼊硬盘
fp.fileno() #返回⼀个长整型的”⽂件标签“
fp.isatty() #⽂件是否是⼀个终端设备⽂件(unix系统中的)
<() #返回下⼀⾏,并将⽂件操作标记位移到下⼀⾏。把⼀个file⽤于for … in file这样的语句时,就是调⽤next()函数来实现遍历的。
fp.seek(offset[,whence]) #将⽂件打操作标记移到offset的位置。这个offset⼀般是相对于⽂件的开头来计算的,⼀般为正数。但如果提供了whence参数就不⼀定
了,whence可以为0表⽰从头开始计算,1表⽰以当前位置为原点计算。2表⽰以⽂件末尾为原点进⾏计算。需要注意,如果⽂件以a或a+的模式打开,每次进⾏写操作时,⽂件操作标记会⾃动返回到⽂件末尾。
(8)⽬录操作:
os.mkdir("file") 创建⽬录
复制⽂件:
复制⽂件夹:
重命名⽂件(⽬录)
移动⽂件(⽬录)
删除⽂件
删除⽬录
<("dir") 空⽬录、有内容的⽬录都可以删
转换⽬录
os.chdir("path") 换路径
2)将⽂件夹下所有图⽚名称加上'_fc'python怎么读取py文件
python代码:
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论