你可以使用内建的dir
函数来列出模块定义的标识符。标识符有函数、类和变量。
当你为dir()
提供一个模块名的时候,它返回模块定义的名称列表。如果不提供参数,它返回当前模块中定义的名称列表。
import sys
dir(sys)-----sys的庞大的属性列表
dir()-------------返回当前模块的属性列表
再定义一个新的变量并赋值a=5,然后再次验证dir()则在属性值中加入了新的值
可以使用del a 则进行删除。
$ python
>>> import sys
>>> dir(sys) # get list of attributes for sys module
['__displayhook__', '__doc__', '__excepthook__', '__name__', '__stderr__',
'__stdin__', '__stdout__', '_getframe', 'api_version', 'argv',
'builtin_module_names', 'byteorder', 'call_tracing', 'callstats',
'copyright', 'displayhook', 'exc_clear', 'exc_info', 'exc_type',
'excepthook', 'exec_prefix', 'executable', 'exit', 'getcheckinterval',
'getdefaultencoding', 'getdlopenflags', 'getfilesystemencoding',
'getrecursionlimit', 'getrefcount', 'hexversion', 'maxint', 'maxunicode',
'meta_path','modules', 'path', 'path_hooks', 'path_importer_cache',
'platform', 'prefix', 'ps1', 'ps2', 'setcheckinterval', 'setdlopenflags',
'setprofile', 'setrecursionlimit', 'settrace', 'stderr', 'stdin', 'stdout',
'version', 'version_info', 'warnoptions']
>>> dir() # get list of attributes for current module
['__builtins__', '__doc__', '__name__', 'sys']
>>>
>>> a = 5 # create a new variable 'a'
>>> dir()
['__builtins__', '__doc__', '__name__', 'a', 'sys']
>>>
>>> del a # delete/remove a name
>>>
>>> dir()
['__builtins__', '__doc__', '__name__', 'sys']
>>>
age = 22
name =
'Swaroop'
print
'%s is %d years old'
% (name, age)
print
'Why is %s playing with that python?'
% name
print
语句可以使用跟着%
符号的项目元组的字符串。这些字符串具备定制的功能。定制让输出满足某种特定的格式。定制可以是%s
表示字符串或%d
表示整数。元组必须按照相同的顺序来对应这些定制。
键值对在字典中以这样的方式标记:d = {key1 : value1, key2 : value2 }
。注意它们的键/值对用冒号分割,而各个对用逗号分割,所有这些都包括在花括号中。
记住字典中的键/值对是没有顺序的。如果你想要一个特定的顺序,那么你应该在使用前自己对它们排序。
字典是dict
类的实例/对象。
ab = { 'Swaroop'
:
'swaroopch@byteofpython.info'
,
'Larry'
:
'larry@wall.org'
,
'Matsumoto'
:
'matz@ruby-lang.org'
,
'Spammer'
:
'spammer@hotmail.com'
}
print
"Swaroop's address is %s"
% ab[
'Swaroop'
]
# Adding a key/value pair
ab[
'Guido'
] =
'guido@python.org'
# Deleting a key/value pair
del
ab[
'Spammer'
]
print
'\nThere are %d contacts in the address-book\n'
%
len
(ab)
for
name, address
in
ab.items():
print
'Contact %s at %s'
% (name, address)
if
'Guido'
in
ab:
# OR ab.has_key('Guido')
print
"\nGuido's address is %s"
% ab[
'Guido'
]
列表、元组和字符串都是序列,但是序列是什么,它们为什么如此特别呢?序列的两个主要特点是索引操作符和切片操作符。
索引同样可以是负数,在那样的情况下,位置是从序列尾开始计算的。因此,shoplist[-1]
表示序列的最后一个元素而shoplist[-2]
抓取序列的倒数第二个项目。
切片操作符是序列名后跟一个方括号,方括号中有一对可选的数字,并用冒号分割。注意这与你使用的索引操作符十分相似。记住数是可选的,而冒号是必须的。
切片操作符是序列名后跟一个方括号,方括号中有一对可选的数字,并用冒号分割。注意这与你使用的索引操作符十分相似。记住数是可选的,而冒号是必须的。
这样,shoplist[1:3]
返回从位置1开始,包括位置2,但是停止在位置3的一个序列切片,因此返回一个含有两个项目的切片。类似地,shoplist[:]
返回整个序列的拷贝。
你可以用负数做切片。负数用在从序列尾开始计算的位置。例如,shoplist[:-1]
会返回除了最后一个项目外包含所有项目的序列切片。
参考
当你创建一个对象并给它赋一个变量的时候,这个变量仅仅 参考 那个对象,而不是表示这个对象本身!也就是说,变量名指向你计算机中存储那个对象的内存。这被称作名称到对象的绑定。
如果你想要复制一个列表或者类似的序列或者其他复杂的对象(不是如整数那样的简单 对象 ),那么你必须使用切片操作符来取得拷贝。如果你只是想要使用另一个变量名,两个名称都参考 同一个对象,那么如果你不小心的话,可能会引来各种麻烦。
print 'Simple Assignment'
shoplist = [
'apple'
,
'mango'
,
'carrot'
,
'banana'
]
mylist = shoplist
# mylist is just another name pointing to the same object!
del
shoplist[
0
]
print
'shoplist is'
, shoplist
print
'mylist is'
, mylist
# notice that both shoplist and mylist both print the same list without
# the 'apple' confirming that they point to the same object
print
'Copy by making a full slice'
mylist = shoplist[:]
# make a copy by doing a full slice
del
mylist[
0
]
# remove first item
print
'shoplist is'
, shoplist
print
'mylist is'
, mylist
# notice that now the two lists are different
输出为:
$ python reference.py
Simple Assignment
shoplist is ['mango', 'carrot', 'banana']
mylist is ['mango', 'carrot', 'banana']
Copy by making a full slice
shoplist is ['mango', 'carrot', 'banana']
mylist is ['carrot', 'banana']
字符串的方法
name = 'Swaroop'
# This is a string object
if
name.startswith(
'Swa'
):
print
'Yes, the string starts with "Swa"'
if
'a'
in
name:
print
'Yes, it contains the string "a"'
if
name.find(
'war'
) !=
-1
:
print
'Yes, it contains the string "war"'
delimiter =
'_*_'
mylist = [
'Brazil'
,
'Russia'
,
'India'
,
'China'
]
print
delimiter.join(mylist)
输出为
$ python str_methods.py
Yes, the string starts with "Swa"
Yes, it contains the string "a"
Yes, it contains the string "war"
Brazil_*_Russia_*_India_*_China
self
self
类的方法与普通的函数只有一个特别的区别——它们必须有一个额外的第一个参数名称,但是在调用这个方法的时候你不为这个参数赋值,Python会提供这个值。这个特别的变量指对象本身,按照惯例它的名称是self
。
给C++/Java/C#程序员的注释
Python中的self
等价于C++中的self
指针和Java、C#中的this
参考。
创建一个类
class Person
:
pass
# An empty block
p = Person()
print
p
使用对象的方法
class Person:
def sayHi(self):
print 'Hello, how are you?'
p = Person()
p.sayHi()
使用__init__方法
__init__
方法在类的一个对象被建立时,马上运行。这个方法可以用来对你的对象做一些你希望的 初始化 。注意,这个名称的开始和结尾都是双下划线。
class Person
:
def
__init__
(self, name):
self.name = name
def
sayHi
(self):
print
'Hello, my name is'
, self.name
p = Person(
'Swaroop'
)
p.sayHi()
我们把__init__
方法定义为取一个参数name
(以及普通的参数self
)。在这个__init__
里,我们只是创建一个新的域,也称为name
。注意它们是两个不同的变量,尽管它们有相同的名字。点号使我们能够区分它们。
给C++/Java/C#程序员的注释
__init__
方法类似于C++、C#和Java中的 constructor 。
有两种类型的 域 ——类的变量和对象的变量,它们根据是类还是对象 拥有 这个变量而区分。
类的变量 由一个类的所有对象(实例)共享使用。只有一个类变量的拷贝,所以当某个对象对类的变量做了改动的时候,这个改动会反映到所有其他的实例上。
对象的变量 由类的每个对象/实例拥有。因此每个对象有自己对这个域的一份拷贝,即它们不是共享的,在同一个类的不同实例中,虽然对象的变量有相同的名称,但是是互不相关的。
使用类与对象的变量:
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()
population属于Person
类,因此是一个类的变量。name
变量属于对象(它使用self
赋值)因此是对象的变量。
观察可以发现__init__
方法用一个名字来初始化Person
实例。在这个方法中,我们让population
增加1
,这是因为我们增加了一个人。同样可以发现,self.name
的值根据每个对象指定,这表明了它作为对象的变量的本质。
我们还看到docstring对于类和方法同样有用。我们可以在运行时使用Person.__doc__
和Person.sayHi.__doc__
来分别访问类与方法的文档字符串
如同__init__
方法一样,还有一个特殊的方法__del__
,它在对象消逝的时候被调用。对象消逝即对象不再被使用,它所占用的内存将返回给系统作它用。在这个方法里面,我们只是简单地把Person.population
减1
。
当对象不再被使用时,__del__
方法运行,但是很难保证这个方法究竟在 什么时候 运行。如果你想要指明它的运行,你就得使用del
语句,就如同我们在以前的例子中使用的那样。
给C++/Java/C#程序员的注释
Python中所有的类成员(包括数据成员)都是 公共的 ,所有的方法都是 有效的 。
只有一个例外:如果你使用的数据成员名称以 双下划线前缀 比如__privatevar
,Python的名称管理体系会有效地把它作为私有变量。
这样就有一个惯例,如果某个变量只想在类或对象中使用,就应该以单下划线前缀。而其他的名称都将作为公共的,可以被其他类/对象使用。记住这只是一个惯例,并不是Python所要求的(与双下划线前缀不同)。
同样,注意__del__
方法与 destructor 的概念类似。
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 Studens
文件:
你可以通过创建一个file
类的对象来打开一个文件,分别使用file
类的read
、readline
或write
方法来恰当地读写文件。对文件的读写能力依赖于你在打开文件时指定的模式。最后,当你完成对文件的操作的时候,你调用close
方法来告诉Python我们完成了对文件的使用。
首先,我们通过指明我们希望打开的文件和模式来创建一个file
类的实例。模式可以为读模式('r'
)、写模式('w'
)或追加模式('a'
)。事实上还有多得多的模式可以使用,你可以使用help(file)
来了解它们的详情。
我们首先用写模式打开文件,然后使用file
类的write
方法来写文件,最后我们用close
关闭这个文件。
接下来,我们再一次打开同一个文件来读文件。如果我们没有指定模式,读模式会作为默认的模式。在一个循环中,我们使用readline
方法读文件的每一行。这个方法返回包括行末换行符的一个完整行。所以,当一个 空的 字符串被返回的时候,即表示文件末已经到达了,于是我们停止循环。
注意,因为从文件读到的内容已经以换行符结尾,所以我们在print
语句上使用逗号来消除自动换行。最后,我们用close
关闭这个文件。
储存器
Python提供一个标准的模块,称为pickle
。使用它你可以在一个文件中储存任何Python对象,之后你又可以把它完整无缺地取出来。这被称为 持久地 储存对象。
还有另一个模块称为cPickle
,它的功能和pickle
模块完全相同,只不过它是用C语言编写的,因此要快得多(比pickle
快1000倍)。你可以使用它们中的任一个,而我们在这里将使用cPickle
模块。记住,我们把这两个模块都简称为pickle
模块。
import cPickle
as p
首先,请注意我们使用了import..as
语法。这是一种便利方法,以便于我们可以使用更短的模块名称。在这个例子中,它还让我们能够通过简单地改变一行就切换到另一个模块
为了在文件里储存一个对象,首先以写模式打开一个file
对象,然后调用储存器模块的dump
函数,把对象储存到打开的文件中。这个过程称为 储存 。
接下来,我们使用pickle
模块的load
函数的返回来取回对象。这个过程称为 取储存 。
(cPickle
或者pickle
)!在程序的其余部分的时候,我们简单地把这个模块称为p
。
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
异常:
当你的程序中出现某些 异常的 状况的时候,异常就发生了。例如,当你想要读某个文件的时候,而那个文件不存在。或者在程序运行的时候,你不小心把它删除了。上述这些情况可以使用异常来处理。
try..except
处理异常
我们可以使用try..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'
我们把所有可能引发错误的语句放在try
块中,然后在except
从句/块中处理所有的错误和异常。except
从句可以专门处理单一的错误或异常,或者一组包括在圆括号内的错误/异常。如果没有给出错误或异常的名称,它会处理 所有的 错误和异常。对于每个try
从句,至少都有一个相关联的except
从句。
如果某个错误或异常没有被处理,默认的Python处理器就会被调用。它会终止程序的运行,并且打印一个消息,我们已经看到了这样的处理。
你还可以让try..catch
块关联上一个else
从句。当没有异常发生的时候,else
从句将被执行。
你可以使用raise
语句 引发 异常。你还得指明错误/异常的名称和伴随异常 触发的 异常对象。你可以引发的错误或异常应该分别是一个Error
或Exception
类的直接或间接导出类。
这个新的异常类型是ShortInputException
类。它有两个域——length
是给定输入的长度,atleast
则是程序期望的最小长度。
class ShortInputException
(Exception):
'''A user-defined exception class.'''
def
__init__
(self, length, atleast):
Exception.__init__(self)
self.length = length
self.atleast = atleast
try
:
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.'
try..finally
假如你在读一个文件的时候,希望在无论异常发生与否的情况下都关闭文件,该怎么做呢?这可以使用finally
块来完成。注意,在一个try
块下,你可以同时使用except
从句和finally
块。如果你要同时使用它们的话,需要把一个嵌入另外一个。
import time
try
:
f = file
(
'poem.txt'
)
while
True
:
# our usual file-reading idiom
line = f.readline()
if
len
(line) ==
0
:
break
time
.sleep(
2
)
print
line,
finally
:
f.close()
print
'Cleaning up...closed the file'
我们进行通常的读文件工作,但是我有意在每打印一行之前用time.sleep
方法暂停2秒钟。这样做的原因是让程序运行得慢一些(Python由于其本质通常运行得很快)。在程序运行的时候,按Ctrl-c中断/取消程序。
我们可以观察到KeyboardInterrupt
异常被触发,程序退出。但是在程序退出之前,finally从句仍然被执行,把文件关闭