十二、模块

sys.path显示环境变量。

dir()全部对象
  globals()全局对象的详细内容
  locals()局部对象的详细内容
  在全局环境里使用,2者没有区别,在子函数里使用的时候,前面加上print或赋值。其实在子函数里没有print都是不打印返回值的。而且如果不用命令行模式,在全局环境里也一样不打印返回值或者是变量的。

代码区域的__name__=='__main__'
  所以可以用这个在模块中使用,防止被import的时候自动运行了。

reload重新导入已经加载成功的模块(没有被导入过会报错),它的作用只是修改模块后,让模块重新加载,相当于del,import。因为import不检查模块是否被更新,如果发现已经存在了,就算被调用不会再加载。

sys.modules显示已经被加载的对象,这里面不是sys.XXX,而是直接使用的模块和方法,以字典的形式出现,可以用keys() values()来获得单独的,一般用sys.modules.keys()就行了。

单独导入 from os import xxx
  阻止模块中某一项导入 from os import _xxx

--------------------------------------------------------------------------------------


十三 类

每个方法,都有一个参数self,相当于C++里的this
  __init__相当于构造函数
  __del__相当于析构函数
  建立子类的方法 class cls(父类的名字):
  可以多重继承,如果有同样的变量或方法,以第一个父类为主。
  如果子类覆盖了父类的方法,那么调用父类方法就用父类.方法(子类的实例,……)。用子类的实例作为第一个参数。如果是构造函数,在子类的构造函数里写:父类.__init__(self,……)

如果在__init__里print self。那么会打印16进制的id,和id(该类的实例)得到的id相同。
  dir(类)和dir(实例)的区别就是后者拥有所有的变量,前者只拥有类中方法外的变量(在方法外定义,不带self的,就是静态变量)和以类增加的变量(如:类.属性=123 )。
  在dir()里只有__name__,__doc__,__module__ 。但是__dict__依然可以使用。

class cls:arg=100 相当与c++里定义了静态成员变量。注意在方法里面使用静态成员,用“类.变量名”。
  python不支持静态成员函数,需要的话,使用一个全局函数来绕过这个限制。就是定义一个全局函数来修改这个类的静态成员变量,这样已经不是类的成员函数了。

这段已经过时了,我当时看的书老了,加@可以用静态成员函数,见:
http://hi.baidu.com/xzq2000/blog/item/91cd8302ed15c4074afb5164.html

cls.__name__ 类的名字
  cls.__doc__ 类的文档
  cls.__dict__ 类的属性
  cls.__bases__ 类的父类//这个只能对类用,不能对实例使用
  cls.__module__ 对类定义的模块

issubclass(sub,sup)判断sub是否是sup的子类。用的时候还要再包一层括号才能print,真怪异。
  isinstance(obj1,class1)obj1是否是class1的实例
  也可以用type对象,如: isinstance(4,type(4))

hasattr(obj1,attr) 检查一个对象是否拥有某个属性
  getattr(obj1,attr) 获得对象的属性的值
  setattr(obj1,attr,set) 设置对象的属性的值
  delattr(obj1,attr) 去掉一个对象的属性

vars(obj1)相当与c=C() c.__dict__ 作用是用字典的形式显示某个实例自己新加的属性及相应的值
  如:>>>class C: ...ver=1 >>>c=C() >>vars(c) {} >>>c.foo=1 >>>vars(c) {'foo':100}
  vars(类)显示出来的变量和dir(类)一致,但是vars(实例)显示的变量比dir(实例)里的少,只出现方法内定义的变量(即self.xx的)和实例.xx='123'定义的变量。

还有一些函数,如果实现可以支持一些操作。
  如实现def __str__(self):return str(self.data)
  当print 这个类的实例时,会打印出data的值。
  另外在__init__里面print self也会调用到这个。
  如实现def __len__(self):return 123
  当对这个类的实例进行len操作时,可以得到123 。
  如果没有实现,那么进行操作要么不理想要么出错。
  如实现__add__,那么可以对实例进行+操作。
  具体参考13.13节,327页。


  在类属性前面加上 __ 可以将它变成私有变量。

  子类重载了父类的函数,那么子类调用的父类方法里如果调用同名函数,那么实际执行的是子类的。要小心。

--------------------------------------------------------------------------------------


十四、环境


dir(__builtins__)可以看见所有的内建函数。

callable 判断一个对象类型是否可以统统用()来调用,即是判断是否是个函数或者是个类。

compile创造一个段代码,第一个参数是代码,第二个是保存这个代码的对象,一般为空。
  最后一个参数有3个值:eval是求值表达式,singel一条可执行语句,exec一组可执行语句。
  >>>eval_code=compile('100+200','','eval')
  >>eval(eval_code)
  300

>>>single_code=compile('print "hello!"','','singel')
  >>>exec singel_code
  hello!

>>>exec_code=compile("""
  ...xxxx
  ...xxxxx
  ...xx
  ''','','exec')
  >>>exec exec_code

eval对一个表达式的字符串求值,如:
  >>>eval('100+200')
  300

exec也可以执行一个py文件里的代码,如:
  >>>f=open('test.py')
  >>>exec f
  执行程序,并把文件指针指向文件末尾。
  等同于 execfile('test.py')可以指定命名空间execfile(filename,globals=globals(),locals=locals())

input等同eval(raw_input())但也有区别,input可以接受包含字母字符串转换成tuple,但是eval接受字母必错。
  如:>>>alist=input('Enter:') 
  123,'aa'
  >>>alist
  (123,'aa')


  intern(str)将一个字符串加入内存,以后赋值同值的变量都是同一个引用ID
  id('124') a1='124' 二者id不同
  intern('123') a2='123' 二者id相同

os.system('date')可以执行操作系统的命令行命令,并输入命令行显示的结果。
  注意os.system没有返回值,如果好获得返回值,应该使用os.popen
  f=os.popen('ls');data=f.readline();f.close;print data

os模块有大量对操作系统进行操作的命令,具体可以查询帮助文件。

res=os.fork 只适合linux,返回是0,表示是子进程,返回非0,表示是父进程。

sys.exit(Statis=0),引发一个SystemExit的异常,如果没有捕获,就直接退出。
  在某些版本下,这个函数一开始就被包括到内联函数里了,可以直接使用。

sys._exit()与sys.exit的区别是,这个函数不做任何扫尾工作,立刻退出python