think python学习笔记(18)

大多数unix系统提供了一个叫做md5sum的命令,来读取一个文件的内容并计算出一个“校验和(checksum)”。不同的内容产生相同校验和的概率非常小。
可以使用一个管道来从python终运行md5sum,并得到计算结果。

filename = 'book.tex'
cmd = 'md5sum' + filename
fp = os.popen(cmd)
res = fp.read()
stat = fp.close()
print(res)
print(stat)

编写模块
任何包含python代码的文件,都可以作为模块被导入。
例如,假设有包含以下代码的文件wc.py

def linecount(filename):
	count = 0
	for line in open(filename):
		count += 1
	return count
print(linecount('wc.py'))	

如果运行这个程序,它将读取自身并打印文件的行数,结果是7。也可以导入模块

>>>import wc
>7

现在有了一个模块对象wc
这个对象提供了linecount函数

wc.linecount('wc.py')

这个例子唯一的问题在于,导入模块后,它将自动运行最后面的测试代码。通常导入一个模块式,它将定义一些新的函数,但是并不运行它们。
作为模块的程序通常写成以下结构

if __name__ == '__main__':
	print(linecount('wc.py'))

__name__是一个在程序开始时设置好的内建变量。如果程序以脚本的形式运行,name__的值为__main,这时其中的代码将被执行。而当其被作为模块导入时,其中的代码将被跳过。
重点:如果导入一个已经导入了的模块,python不会做任何事情,它不会重新读取文件,即使文件的内容已经发生了改变。
如果要重载一个模块,可以使用内建函数reload,但它可能会出错。因此最安全的方法是重启编辑器,然后重新导入模块。

调试
当读写文件时,可能会遇到空白带来的问题。这些问题会很难调试,因为空格、制表符和换行符通常是看不见的:

s = '1 2\t 3\n 4'
print(s)

内建函数repr可以用来解决这个问题。它接受任意一个对象作为参数,然后返回该对象的字符串表示。对于空白符号,它将用反斜杠序列表示

>>>print(repr(s))
>'1 2\t 3\n 4'

这个对于调试会很有用
另一个可能会遇到的问题是,不同的系统使用不同的符号来表示一行的结束。有些系统使用换行符\n,有的使用返回符号\r,有的两者都是用。如果在不同的系统中移动文件,这些差异会导致问题。
对于大多数系统,有一些转换不同格式文件的应用。

类和对象
程序员自定义类型
我们已经使用了很多python内置类型。现在要定义一个新类型。
下面创建一个point类型,代表二维空间中的一个点。
在数学计法中,点通常被写成在两个小括号中用一个逗号分隔坐标的形式。
在python中,有几种表示点的方法:
1.可以将坐标存储在两个独立的变量,x和y中
2.可以将坐标作为一个列表或者元组的元素存储
3.可以创建一个新类型将点表示为对象

程序员自定义类型也被称作类。像这样定义一个对象

class point:
	"""Represents a point in 2-D space"""

头部语句表明新类的名称是Point。主体部分是文档字符串,用来解释这个类的用途。也可以在一个类的定义中定义变量和函数。
定义一个叫做Point的类将创建饿了一个类对象

>>>Point
><class '__main__.point'>

由于Point是定义在顶层的,所以它的全名是__main__Point。
类对象就像是一个用来创建对象的工厂。要创建一个点,可以像调用函数那样调用Point。

blank = Point()

返回值是一个Point对象的引用,我们将它赋值给blank
创建一个新对象的过程叫做实例化,这个新对象叫做这个类的一个实例。
当试图打印一个类,python会显示它属于哪个类,以及它在内存中的存储地址。
(前缀0x代表紧跟后面的数是以十六进制表示的)。
每一个对象都是某种类的施力,所以对象和实例可以互换。

属性
可以使用点标记法向一个实例进行赋值操作

>>>blank.x =3.0
>>>blank.y =4.0

这个语法类似于从一个模块中使用变量的语法,比如math.pi和string.whitespace。在此例中,是给一个类中已命名的元素赋值,这类元素叫做属性。
说明一个对象及其属性的状态图叫做对象图。
变量blank引用了一个Point类,这个类拥有了两个属性。每个属性都引用了一个浮点数。
可以使用相同的语法读取一个属性的值:

>>>blank.y
>4.0
>>>x = blank.x
>>>x
>3.0

表达式blank.x的意思是,前往blank所引用的对象并且获取x的值。在此例中,我们将获取到的值赋值给了一个叫做x的变量。变量x和属性x并不会冲突。
可以在任何表达式中使用点标记法,例如。

>>>'(%g,%g)'%(blank.x,blank.y)
>>>distance = math.sqrt(blank.x**2 + blank.y**2)

可以将一个实例作为参数传递,例如:

def print_point(p):
	print('(%g,%g)' % (p.x,p.y))

print_point接受一个点作为参数,打印出其在数学中的表示方法。调用它的时候,可以将blank作为参数传递。

>>>print_point(blank)

在这个函数内部,p是blank的别名,所以如果函数修改了p,blank也会随之改变。

矩形
有时候,一个对象该拥有哪些属性是显而易见的,但有时需要好好考虑一番。
比如,设计一个矩形的类,为了描述一个矩形的位置和大小,需要设即哪些属性。
为了简化模型,这里假设矩形是水平或者竖直的。
至少有两种可能的设计:
1.可以指定矩形的一个角(或者中心)、宽度以及长度。
2.可以指定对角线上的两个角

类的定义:

class rectangle:
	"""Represents a rectangle.
	attributes : width height,corner.
	"""

文档字符串中列出了属性:width和height是数字,corner是一个Point对象,代表左下角的点。
为了描述一个矩形,需要实例化一个rectangle对象,并为它的属性赋值。

box = rectangle()
box.width = 100.0
box.height = 200.0
box.corner = Point()
box.corner.x = 0.0
box.corner.y = 0.0

表达式box.corner.x的意思是,前往box所引用的对象,找到叫做Corner的属性,然后前往Corner所引用的对象,找到x的属性。
一个对象作为另一个对象的属性叫做嵌套

实例作为返回值
函数可以返回实例。
例:find_center接受一个Rectangle作为参数,返回一个Point,代表了这个Rectangle的中心坐标。

def find_center(rect):
	p = Point()
	p.x = rect.corner.x + rect.width/2
	p.y = rect.corner.y + rect.height/2
	return p

下面这个例子将box作为参数传递,然后将返回的point赋值给center

center = find_center(box)
print_point(center)

对象是可变的
可以通过给一个对象的属性赋值来改变这个对象的状态。
例如要改变一个矩形的大小而不改变它的位置,可以修改width和height的值。

box.width = box.width + 50
box.height = box.height + 100

也可以便携盒你数来修改对象。
例:grow_rectangle接受一个rectangle对象和两个数字,dwidth和dheight,并将其加到矩形的宽度和高度上。

def grow_rectangle(rect,dwidth,dheight):
	rect.width += dwidth
	rect.height += dheight

grow_rectangle(box,50,100)	

在函数内部,rect是box的一个别名,所以如果函数修改了rect,则box也随之改变。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值