python笔记(4)

面对对象

1
2
3
4
5
6
7
8
9
class Person:
def __init__(self, name):
self.name = name

def say(self):
print("Hello!\nMy name is {}".format(self.name))

p = Person("Peter")
p.say()

这里的self是一个相当于this指针一样的东西。

这里相当于Person.say(p),即任何没有参数的函数也都需要它。

__init__()是一个构造函数。

类变量

1
2
3
4
5
6
7
8
9
10
class Person:
population = 0

def __init__(self, name):
self.name = name
Person.population += 1

@classmethod
def howMany(cls):
print(Person.population)

这里的population属于整个类,某个实例拥有的变量会覆盖类拥有的变量。

Person.populationself.__class__.population是相同的效果。

@classmethod是一个装饰器,标记该方法是一个类方法。

这等效于howMany = classmethod(howMany)

注:任何属性都是公开的,除非标识符使用__开头。

继承

python可以多继承。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Person:
def __init__(self, name):
self.name = name

def say(self):
print("My name is {}.".format(self.name))

class Teenager(Person):
def __init__(self, name, age):
Person.__init__(self, name)
self.age = age

def say(self):
Person.say(self)
print("I'm {}-year-old.".format(self.age))

t = Teenager("Bob", 13)
t.say()

新建类后面的括号是一个Tuple,可以有多个类名,访问按照指定顺序进行。

输入与输出

input()进行读入,参数是输入提示;print()进行输出。

文件操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
poem = '''\
Programming is fun
When the work is done
if you wanna make your work also fun:
use Python!
'''

f = open("poem.txt", "w")
f.write(poem)
f.close()

f = open("poem.txt", "r")
while 1:
line = f.readline()
#EOF的长度为0
if len(line) == 0:
break

print(line, end='')
f.close()

open()提供encoding=可以指定为"utf-8"等编码。

Pickle

可以持久的存储对象,打开文件需要二进制选项('b'),其次,使用pickle.dumppickle.load存储和读取。

异常

使用try except语句处理异常,同样可以加入elsefinally可以在任何情况下运行。

通常使用try读取资源而用finally释放资源。

可以用as将异常对象命名,raise可以抛出异常。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class TestTooShortError(Exception):
def __init__(self, s):
Exception.__init__(self)
self.lenth = len(s)

try:
s = input()
if len(s) < 20:
raise TestTooShortError(s)
except EOFError:
print("You give me an EOF.")
except TestTooShortError as er:
print("The test is too short.")
else:
print (s)

这里的自己定义的异常需要继承。

1
2
3
4
5
6
7
8
9
10
11
try:
f = open("1.txt")
for line in f:
print(line, end='')
except IOError:
print("Can't find the file.")
except KeyboardInterrupt:
print("You cancelled it.")
finally:
if f:
f.close()

这里的finally语句是在释放资源,保证文件被关闭。

使用with语句更加方便:

1
2
3
with open("1.txt") as f:
for line in f:
print(line, end='')

这里的过程中,保证会调用__enter__()__exit__()方法。

处理import的异常

导入库如果它不存在或是找不到时,或许只是希望程序跳过某些部分,而不是崩溃。

1
2
3
4
try:
import chardet
except ImportError:
chardet = None

此时检查是否导入就非常的简单:

1
2
3
4
if chardet:
# do something
else:
# continue anyway

某些时候希望使用某个库的另一个实现(它可能更快,更稳定),只需要在抛出异常后,在except后写下import somethingSlower as somethingFaster,从而避免重名的麻烦。

断言

assert后接表达式,错误后直接抛出异常。

os模块

os.getcwd()(访问当前目录),os.chdir()(变更工作目录)。

处理路径(os.path)

1
2
print(os.path.join(os.path.expanduser('~'), 'diveintopython3', 'examples', 'humansize.py')) 
c:\Users\pilgrim\diveintopython3\examples\humansize.py

join()可以在不同的平台加入不同的分隔符,将路径转为绝对路径(也可以使用realpath()),并会在必要的时候加入分隔符,接受多个参数。

还有可以分离路径和文件名的:split(),将返回一个元组;分离文件名和后缀名的:splitext()

通配符匹配文件(glob)

glob.glob('examples/*.xml')这将返回符合的所有的文件名组成的列表。

获取元数据(os.stat()

这包括很多的元数据,修改时间(st_mtime),大小(st_size)但它们的返回值需要些处理才能看得懂。

推导

列表推导

1
2
listone = [2, 3, 4]
listtwo = [2*i for i in listone if i > 2]

[(os.stat(f).st_size, os.path.realpath(f)) for f in glob.glob('*.xml')]任何表达式都可以。

字典推导

metadata_dict = {f:os.stat(f) for f in glob.glob('*test*.py')}与列表推导类似。

可以用来交换键和值:{value:key for key, value in a_dict.items()}

集合解析

{2**x for x in range(10)}这与列表的类似。