'''the doc of fun,fun is also an abstract,can use in help()'''
global x #state overall var by using global var in fun
x=2
print "x is:",x,"\n"
x=50
print "x is:",x,"\n"
print "After going to fun:\n"
fun()
print fun.__doc__
Help on function fun in module __main__:
fun()
the doc of fun,fun is also an abstract
#!/usr/bin/python
# Filename: using_sys.py
import
sys
print
'The command line arguments are:'
for
i
in
sys
.argv:
print
i
print
'\n\nThe PYTHONPATH is'
,
sys
.path,
'\n'
sys
模块包含了与Python解释器和它的环境有关的函数。
#!/usr/bin/python
# Filename: mymodule.py
def
sayhi
():
print
'Hi, this is mymodule speaking.'
version =
'0.1'
#!/usr/bin/python
# Filename: mymodule_demo.py
import
mymodule
mymodule.sayhi()
print
'Version'
, mymodule.version
第十一章:解决问题
域有两种类型——属于每个实例/类的对象或属于类本身。它们分别被称为实例变量和类变量。
类使用class 关键字创建。类的域和方法被列在一个缩进块中。
Python中所有的类成员(包括数据成员)都是 公共的 ,所有的方法都是 有效的 。
如果你使用的数据成员名称以 双下划线前缀 比如__privatevar
,Python的名称管理体系会有效地把它作为私有变量。
这样就有一个惯例,如果某个变量只想在类或对象中使用,就应该以单下划线前缀。而其他的名称都将作为公共的,可以被其他类/对象使用。记住这只是一个惯例,并不是Python所要求的(与双下划线前缀不同)。
同样,注意__del__
方法与 destructor 的概念类似。
#!/usr/bin/python
# Filename: objvar.py
class
Person
:
'''Represents a person.'''
population =
0
def
__init__
(self, name):
'''Initializes the person's data.'''
self.name = name
print
'(Initializing %s)'
% self.name
# When this person is created, he/she
# adds to the population
Person.population +=
1
def
__del__
(self):
'''I am dying.'''
print
'%s says bye.'
% self.name
Person.population -=
1
if
Person.population ==
0
:
print
'I am the last one.'
else
:
print
'There are still %d people left.'
% Person.population
def
sayHi
(self):
'''Greeting by the person.
Really, that's all it does.'''
print
'Hi, my name is %s.'
% self.name
def
howMany
(self):
'''Prints the current population.'''
if
Person.population ==
1
:
print
'I am the only person here.'
else
:
print
'We have %d persons here.'
% Person.population
swaroop = Person(
'Swaroop'
)
swaroop.sayHi()
swaroop.howMany()
kalam = Person(
'Abdul Kalam'
)
kalam.sayHi()
kalam.howMany()
swaroop.sayHi()
swaroop.howMany()
面向对象的编程带来的主要好处之一是代码的重用,实现这种重用的方法之一是通过 继承 机制。
如果为教师和学生两个独立的类添加共同的属性,比较好的方法是创建一个共同的类称为SchoolMember。
然后让教师和学生的类 继承 这个共同的类。即它们都是这个类型(类)的子类型,然后我们再为这些子类型添加专有的属性。
优点是,如果增加/改变了SchoolMember
中的功能,它会自动地反映到子类中。
然而,在一个子类型之中做的改动不会影响到别的子类型。
另外一个优点是你可以把教师和学生对象都作为SchoolMember
对象来使用,这在某些场合特别有用,比如统计学校成员的人数。
一个子类型在任何需要父类型的场合可以被替换成父类型,即对象可以被视作是父类的实例,这种现象被称为多态现象。(???与C++的区别???)
在 重用 父类的代码的时候,无需在不同的类中重复它。而如果我们使用独立的类的话,我们就不得不这么做了。
在上述的场合中,SchoolMember
类被称为 基本类 或 超类 。而Teacher
和Student
类被称为 导出类 或 子类 。
#!/usr/bin/python
# Filename: inherit.py
class
SchoolMember
:
'''Represents any school member.'''
def
__init__
(self, name, age):
self.name = name
self.age = age
print
'(Initialized SchoolMember: %s)'
% self.name
def
tell
(self):
'''Tell my details.'''
print
'Name:"%s" Age:"%s"'
% (self.name, self.age),
class
Teacher
(SchoolMember):
'''Represents a teacher.'''
def
__init__
(self, name, age, salary):
SchoolMember.__init__(self, name, age)
self.salary = salary
print
'(Initialized Teacher: %s)'
% self.name
def
tell
(self):
SchoolMember.tell(self)
print
'Salary: "%d"'
% self.salary
class
Student
(SchoolMember):
'''Represents a student.'''
def
__init__
(self, name, age, marks):
SchoolMember.__init__(self, name, age)
self.marks = marks
print
'(Initialized Student: %s)'
% self.name
def
tell
(self):
SchoolMember.tell(self)
print
'Marks: "%d"'
% self.marks
t = Teacher(
'Mrs. Shrividya'
,
40
,
30000
)
s = Student(
'Swaroop'
,
22
,
75
)
print
# prints a blank line
members = [t, s]
for
member
in
members:
member.tell()
# works for both Teachers and Students
Python总是首先查找对应类型的方法,如果不能在导出类中找到对应的方法,才开始到基本类中逐个查找。
#!/usr/bin/python
# Filename: using_file.pypoem =
'''\
Programming is fun
When the work is done
if you wanna make your work also fun:
use Python!
'''f =
file
(
'poem.txt'
,
'w'
)
# open for 'w'riting
f.write(poem)
# write text to file
f.close()
# close the file
f =
file
(
'poem.txt'
)
# if no mode is specified, 'r'ead mode is assumed by default
while
True
:
line = f.readline() if
len
(line) ==
0
:
# Zero length indicates EOF
break
print
line,
# Notice comma to avoid automatic newline added by Python
f.close()
# close the file
我们首先用写模式打开文件,然后使用file
类的write
方法来写文件,最后我们用close
关闭这个文件。
接下来,我们再一次打开同一个文件来读文件。如果我们没有指定模式,读模式会作为默认的模式。在一个循环中,我们使用readline
方法读文件的每一行。这个方法返回包括行末换行符的一个完整行。所以,当一个 空的 字符串被返回的时候,即表示文件末已经到达了,于是我们停止循环。
注意,因为从文件读到的内容已经以换行符结尾,所以我们在print
语句上使用逗号来消除自动换行。最后,我们用close
关闭这个文件。
#!/usr/bin/python
# Filename: pickling.py
import
cPickle
as p
#import pickle as p
shoplistfile =
'shoplist.data'
# the name of the file where we will store the object
shoplist = [
'apple'
,
'mango'
,
'carrot'
]
# Write to the file
f =
file
(shoplistfile,
'w'
)
p.dump(shoplist, f)
# dump the object to a file
f.close()
del
shoplist
# remove the shoplist
# Read back from the storage
f =
file
(shoplistfile)
storedlist = p.load(f)
print
storedlist
为了在文件里储存一个对象,首先以写模式打开一个file
对象,然后调用储存器模块的dump
函数,把对象储存到打开的文件中。这过程称为 储存 。
接下来,我们使用pickle
模块的load
函数的返回来取回对象。这个过程称为 取储存 。
SyntaxError语法错误
EOFError
的错误,这个错误基本上意味着它发现一个不期望的 文件尾
我们把所有可能引发错误的语句放在try
块中,然后在except
从句/块中处理所有的错误和异常。except
从句可以专门处理单一的错误或异常,或者一组包括在圆括号内的错误/异常。如果没有给出错误或异常的名称,它会处理 所有的 错误和异常。对于每个try
从句,至少都有一个相关联的except
从句。
import
sys
try
:
s =
raw_input
(
'Enter something --> '
)
except
EOFError:
print
'\nWhy did you do an EOF on me?'
sys
.exit()
# exit the program
except
:
print
'\nSome error/exception occurred.'
# here, we are not exiting the program
print
'Done'
你可以使用raise
语句 引发 异常。你还得指明错误/异常的名称和伴随异常 触发的 异常对象。你可以引发的错误或异常应该分别是一个Error
或Exception
类的直接或间接导出类。
#!/usr/bin/python
# Filename: raising.pyclass
ShortInputException
(Exception):
'''A user-defined exception class.'''
def
__init__
(self, length, atleast):
Exception.__init__(self)
self.length = length
self.atleast = atleasttry
:
s = raw_input
(
'Enter something --> '
)
if
len
(s) <
3
:
raise ShortInputException(len
(s),
3
)
# Other work can continue as usual here
except
EOFError:
print
'\nWhy did you do an EOF on me?'
except
ShortInputException, x:
print
'ShortInputException: The input was of length %d, \
was expecting at least %d' % (x.length, x.atleast)
else
:
print
'No exception was raised.'
假如你在读一个文件的时候,希望在无论异常发生与否的情况下都关闭文件,该怎么做呢?这可以使用finally
块来完成。注意,在一个try
块下,你可以同时使用except
从句和finally
块。
第十四章:标准库
-
os.name
字符串指示你正在使用的平台。比如对于Windows,它是'nt'
,而对于Linux/Unix用户,它是'posix'
。 -
os.getcwd()
函数得到当前工作目录,即当前Python脚本工作的目录路径。 -
os.getenv()
和os.putenv()
函数分别用来读取和设置环境变量。 -
os.listdir()
返回指定目录下的所有文件和目录名。 -
os.remove()
函数用来删除一个文件。 -
os.system()
函数用来运行shell命令。 -
os.linesep
字符串给出当前平台使用的行终止符。例如,Windows使用'\r\n'
,Linux使用'\n'
而Mac使用'\r'
。 -
os.path.split()
函数返回一个路径的目录名和文件名。>>> os.path.split('/home/swaroop/byte/code/poem.txt')
('/home/swaroop/byte/code', 'poem.txt') -
os.path.isfile()
和os.path.isdir()
函数分别检验给出的路径是一个文件还是目录。类似地,os.path.existe()
函数用来检验给出的路径是否真地存在。
第十五章:
名称 | 说明 |
---|---|
__init__(self,...) | 这个方法在新建对象恰好要被返回使用之前被调用。 |
__del__(self) | 恰好在对象要被删除之前调用。 |
__str__(self) | 在我们对对象使用print 语句或是使用str() 的时候调用。 |
__lt__(self,other) | 当使用 小于 运算符(<)的时候调用。类似地,对于所有的运算符(+,>等等)都有特殊的方法。 |
__getitem__(self,key) | 使用x[key] 索引操作符的时候调用。 |
__len__(self) | 对序列对象使用内建的len() 函数的时候调用。 |
listone = [
2
,
3
,
4
]
listtwo = [
2
*i
for
i
in
listone
if
i >
2
]
print
listtwo
由于在args
变量前有*
前缀,所有多余的函数参数都会作为一个元组存储在args
中。如果使用的是**
前缀,多余的参数则会被认为是一个字典的键/值对。
当要使函数接收元组或字典形式的参数的时候,有一种特殊的方法,它分别使用*
和**
前缀。
种方法在函数需要获取可变数量的参数的时候特别有用。
由于在args
变量前有*
前缀,所有多余的函数参数都会作为一个元组存储在args
中。如果使用的是**
前缀,多余的参数则会被认为是一个字典的键/值对。
>>> def powersum(power, *args):
... '''Return the sum of each argument raised to specified power.'''
... total = 0
... for i in args:
... total += pow(i, power)
... return total
...
>>> powersum(2, 3, 4)
25
lambda语句:
def
make_repeater
(n):
return lambda
s: s*n
twice = make_repeater(2
)
print
twice(
'word'
)
print
twice(
5
)
output:
$ python lambda.py
wordword
10
我们使用了
make_repeater
函数在运行时创建新的函数对象,并且返回它。lambda
语句用来创建函数对象。本质上,lambda
需要一个参数,后面仅跟单个表达式作为函数体,而表达式的值被这个新建的函数返回。注意,即便是print
语句也不能用在lambda形式中,只能使用表达式。
exec
语句用来执行储存在字符串或文件中的Python语句。
eval
语句用来计算存储在字符串中的有效Python表达式。
assert
语句用来声明某个条件是真的。例如,如果你非常确信某个你使用的列表中至少有一个元素,而你想要检验这一点,并且在它非真的时候引发一个错误,那么assert
语句是应用在这种情形下的理想语句。当assert语句失败的时候,会引发一个AssertionError
。
repr
函数用来取得对象的规范字符串表示。
>>> i = []
>>> i.append('item')
>>> `i`
"['item']"
>>> repr(i)
"['item']"