python库

python中有两个模块在python启动时载入,任何程序都可以使用它们,因此它们非常重要

1,内建函数模块 __builtin__

2,异常处理相关模块 exceptions

 

Python有很多使用了POSIX标准API和标准C语言库的模块,它们为底层操作系统提供了平台独立的接口:

eg:

提供文件和进程处理功能的os模块

提供平台独立的文件名处理(分拆目录名,文件名,后缀等)的os.path模块

时间日期处理相关的time/datatime

 

其实网络和线程也可是算这一类

 

标准库里面还有很多用于支持内建类型操作的库

string 模块实现了字符串处理

math 提供数学计算操作和常量(pi,e)

cmath 模块为复数提供了和math一样的功能

 

而且python还提供了正则表达式的支持的re模块

 

sys模块可以让你访问解释器相关参数,比如模块搜索路径,解释器版本等

operator模块提供了和内建操作符相同的函数

copy模块允许复制对象

gc模块提供了对垃圾收集的相关控制功能

 

下面详细的看看这些模块的功能吧:

 

__builtin__模块

  该模块包含了Python使用的内建函数,一般不用手动倒入这个模块

apply函数:

#builtin-apply-example-1.py



def function(a,b):

    print a,b





apply(function,("whither","canada?"))

apply(function,(1,2+3))


输出:

>>> ================================ RESTART ================================

>>> 

whither canada?

1 5

 

 

apply的第三个参数可以接受关键字参数:(以字典形式)

#builtin-apply-example-2.py



def function(a,b):

    print a,b





apply(function,("crunchy","frog"))

apply(function,("crunchy",),{"b":"frog"})

apply(function,(),{"a":"crunchy","b":"frog"})


结果:

>>> ================================ RESTART ================================

>>> 

crunchy frog

crunchy frog

crunchy frog

 

 

apply函数的一个常见用法是把构造函数参数从子类传到到基类,尤其是构造函数需要接受很多参数的时候:

#builtin-apply-example-3.py



class Rectangle:

    def __init__(self,color="white",width=10,height=10):

        print "create a",color,self,"sized",width,"x",height



class RoundedRectangle(Rectangle):

    def __init__(self,**kw):

        apply(Rectangle.__init__,(self,),kw)



rect = Rectangle(color="green",height=100,width=100)

rect = RoundedRectangle(color="blue",height=20)

结果:

>>> ================================ RESTART ================================

>>> 

create a green <__main__.Rectangle instance at 0x0000000002A80888> sized 100 x 100

create a blue <__main__.RoundedRectangle instance at 0x0000000002A7E088> sized 10 x 20

>>> 

 

下面两个语句是等价的:

result = function(*args,**kwargs)

result = apply(function,args,kwargs)

 

加载重载模块:

我们经常用import导入其他模块,其实这个import其实是靠内建函数__import__来工作的。

功过这个方法可以动态的调用函数

当知道模块名称时候,可以很方便倒入所有以"-plugin"结尾的模块:

LOOK:

#builtin-import-example-1.py



import glob,os



modules = []



for module_file in glob.glob("*-plugin.py"):

    try:

        module_name,ext = os.path.splitext(os.path.basename(module_file))

        module = __import__(module_name)

        modules.append(module)

    except ImportError:

        pass



for module in modules:

    module.hello()

 

#example-plugin.py



def hello():

    print "example-plugin says hello"

 

结果:

example-plugin says hello

此处注意:plug-in模块文件名中有一个“-”.这意味着不能使用普通的import命令,因为Python的辨识符不允许有“-”

可以用__import__函数获得特定函数:

#builtin-import-example-2.py



import glob,os



def getfunctionbyname(module_name,function_name):

    module = __import__(module_name)

    return getattr(module,function_name)



print repr(getfunctionbyname("dumbdbm","open"))

结果:

>>> ================================ RESTART ================================

>>> 

<function open at 0x0000000002BE0208>

>>> 

 

也可以用__import__实现延迟导入:

#builtin-import-example-3.py



class LazyImport:

    def __init__(self,module_name):

        self.module_name = module_name

        self.module = None

    def __getattr__(self,name):

        if self.module is None:

            self.module = __import__(self.module_name)

        return getattr(self.module,name)



string = LazyImport("string")



print string.lowercase

结果:

>>> ================================ RESTART ================================

>>> 

abcdefghijklmnopqrstuvwxyz

>>> 

该例子string模块只在第一次使用的时候导入

重新加载函数reload():

 

#builtin-reload-example-1.py



import hello

reload(hello)

reload(hello)

reload(hello)

注意:当重新加载模块时,它会被重新编译,新的模块会代替模块字典里的老模块
但是,已经用原模块里的类建立的实例仍然使用的时老模块(不会被更新)

同样的,使用from - import直接创建的到模块内容的引用也是不会被更新的。

 

 dir函数:

返回由给定模块,类,实例或其他类型的所有成员的列表。

可在交互式解释器下直接dir()

#builtin-dir-example-1.py



def dump(value):

    print value,"=>",dir(value)



import sys



dump(0)

dump(1.0)

dump(0.0j)

dump([])

dump({})

dump("string")

dump(len)

dump(sys)

 

#builtin-dir-example-2.py



class A:

    def a(self):

        pass

    def b(self):

        pass



class B(A):

    def c(self):

        pass

    def d(self):

        pass

def getmembers(klass,members=None):

    #get a list of all class members,ordered by class

    if members is None:

        members = []

    for k in klass.__bases__:

        getmembers(k,members)

    for m in dir(klass):

        if m not in members:

            members.append(m)

    return members



print getmembers(A)

print getmembers(B)

print getmembers(IOError)

结果:

>>> ================================ RESTART ================================

>>> 

['__doc__', '__module__', 'a', 'b']

['__doc__', '__module__', 'a', 'b', 'c', 'd']

['__class__', '__delattr__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__dict__', '__getitem__', '__getslice__', '__setstate__', '__unicode__', 'args', 'message', 'errno', 'filename', 'strerror']

>>> 


getmembers函数返回一个有序列表,成员在列表中名称出现的越早,它所处的类层次就越高。

字典是无序的,而列表和元组诗有序的

            

 vars函数

返回的是包含每个成员当前值得字典。如果使用不带参数的vars,将返回当前局部名称空间的可见元素(同locals()函数)

#builtin-vars-example-1.py



book = "library2"

pages = 250

scripts = 350



print "the %(book)s book contaions more than %(scripts)s scripts" % vars()

结果:

>>> ================================ RESTART ================================

>>> 

the library2 book contaions more than 350 scripts

>>> 

 

Python是一种动态类型语言,这就是说给一个变量名可以在不同场合绑定到不同的类型上。type函数允许检查一个变量的类型,这个函数返回一个

type descriptor(类型描述符),它对于每个类型是不一样的:

#builtin-type-example-1.py



def dump(value):

    print type(value),value



dump(1)

dump(1.0)

dump("one")

result:

>>> ================================ RESTART ================================

>>> 

<type 'int'> 1

<type 'float'> 1.0

<type 'str'> one

>>> 


每个类型都有一个对应的类型对象,可以使用is操作符来检查类型

 

#builtin-type-example-2.py



def load(file):

    if isinstance(file,type("")):

        file = open(file,"rb")

    return file.read()



print len(load("builtin-vars-example-1.py")),"bytes"

print len(load(open("builtin-vars-example-1.py"))),"bytes"

 

>>> type("")

<type 'str'>

>>> 

 

result:

>>> ================================ RESTART ================================

>>> 

254 bytes

245 bytes

>>> 

 

 calable函数

    检查一个对象是否是可调用的(无论是直接调用或是通过apply)。

对于函数,方法,lambda函式,类,以及实现了__call__方法的类实例,都返回True

#builtin-callable-example-1.py



def dump(function):

    if callable(function):

        print function,"is callable"

    else:

        print function,"is *not* callable"





class A:

    def method(self,value):

        return value



class B(A):

    def __call__(self,value):

        return value



a = A()

b = B()



dump(0)

dump("string")

dump(callable)

dump(dump)



dump(A)

dump(B)

dump(B.method)



dump(a)

dump(b)

dump(b.method)

result:

>>> ================================ RESTART ================================

>>> 

0 is *not* callable

string is *not* callable

<built-in function callable> is callable

<function dump at 0x00000000020F0908> is callable

__main__.A is callable

__main__.B is callable

<unbound method B.method> is callable

<__main__.A instance at 0x0000000002AF01C8> is *not* callable

<__main__.B instance at 0x0000000002AF0888> is callable

<bound method B.method of <__main__.B instance at 0x0000000002AF0888>> is callable

>>> 

 

注意,A和B是可调用的,如果调用它们,就产生新的对象(类实例),但是A类实例不可调用,因为没有实现__call__方法

 

可以在operator模块中找到检查对象是否为某一内建类型(数字,序列,字典等)的函数,因为创建一个类很简单,所以对这些类型使用显式的类型判断并不是好想法

在处理类和实例的时候会复杂些,Python不会把类作为本质上的类型对待;相反的,所有类都属于一个特殊的类型,所有的类实例属于一个特殊的实例类型

 

>>> b = a()

>>> type(a)

<type 'classobj'>

>>> type(b)

<type 'instance'>

>>> c = a()

>>> type(a)

<type 'classobj'>

>>> type(c)

<type 'instance'>

>>> 

所以,不能使用type函数来测试一个实例是否属于一个给定的类。

所有实例都是同样的类型!

为了解决这个问题,可以使用isinstance函数。它会检查一个对象是不是给定类(或其子类)的实例

#builtin-isinstance-example-1.py



class A:

    pass



class B:

    pass



class C(A):

    pass



class D(A,B):

    pass



def dump(object):

    print object,"=>",



    if isinstance(object,A):

        print "A",

    if isinstance(object,B):

        print "B",

    if isinstance(object,C):

        print "C",

    if isinstance(object,D):

        print "D"



    print



a = A()

b = B()

c = C()

d = D()

d

dump(a)

dump(b)

dump(c)

dump(d)

dump(0)

dump("string")

result:

>>> ================================ RESTART ================================

>>> 

<__main__.A instance at 0x0000000002C601C8> => A

<__main__.B instance at 0x0000000002C60888> => B

<__main__.C instance at 0x0000000002C60B88> => A C

<__main__.D instance at 0x0000000002C60B08> => A B D



0 =>

string =>

>>> 

 

issubclass函数和isinstance类似,它用于检查一个类对象是否与给定类相同,或者是给定类子类

注意:isinstance可以接受任何对象作为参数,而issubclass函数在接受类对象参数时会引发TypeError异常,第一个参数必须是类

#builtin-issubclass-example-1.py



class A:

    pass



class B:

    pass



class C(A):

    pass



class D(A,B):

    pass



def dump(object):

    print object,"=>",



    if issubclass(object,A):

        print "A",

    if issubclass(object,B):

        print "B",

    if issubclass(object,C):

        print "C",

    if issubclass(object,D):

        print "D"



    print





dump(A)

dump(B)

dump(C)

dump(D)

dump(0)

dump("string")

result:

>>> ================================ RESTART ================================

>>> 

__main__.A => A

__main__.B => B

__main__.C => A C

__main__.D => A B D



0 =>



Traceback (most recent call last):

  File "H:/python/strandarlib/builtin-vars-example-1.py", line 34, in <module>

    dump(0)

  File "H:/python/strandarlib/builtin-vars-example-1.py", line 18, in dump

    if issubclass(object,A):

TypeError: issubclass() arg 1 must be a class

>>> 

 

Python提供了在程序中与解释器交互的很多方法

eval函数将一个字符串作为python表达式求值,可以传递一串文本,简单的表达式,或者使用内建python函数

#builtin-eval-example-1.py



def dump(expression):

    result = eval(expression)

    print expression,"=>",result,type(result)



dump("1")

dump("1.0")

dump("'string'")

dump("1.0+2.0")

dump("'*'*10")

dump("len('world')")

result:

>>> ================================ RESTART ================================

>>> 

1 => 1 <type 'int'>

1.0 => 1.0 <type 'float'>

'string' => string <type 'str'>

1.0+2.0 => 3.0 <type 'float'>

'*'*10 => ********** <type 'str'>

len('world') => 5 <type 'int'>

>>> 

当如这样存在风险(引入os模块,删除磁盘上文件)

#builtin-eval-example-2.py



print eval("__import__('os').getcwd()")

print eval("__import__('os').remove('file')")

eval第二个参数,定义了该表达式求值时命名空间字典

print eval("__import__('os').getcwd()")

print eval("__import__('os').remove('file')",{"__builtins__":{}})

即使这样,仍然无法避免针对cpu和内存资源的攻击

eval("'*'*1000000*2*2*2*2*2*2*2*2*2")会使程序耗尽资源

 

compile函数:

#builtin-compile-example-1.py



NAME = "builtin-apply-example-1.py"

BODY = """print 'owl-stretching time'"""



try:

    compile(BODY,NAME,"exec")

except SyntaxError,v:

    print "syntax error: ",v,"in",NAME

 

#builtin-compile-example-2.py





BODY = """

    print 'owl-stretching time'

    """



code = compile(BODY,"<script>","exec")



print code

exec code

 

可以在程序中执行实时的生成代码。

#builtin-compile-example-3.py





import sys,string



class CodeGeneratorBackend:

    "Simple code genetator for Python"



    def begin(self,tab='\t'):

        self.code = []

        self.tab = tab

        self.level = 0



    def end(self):

        self.code.append("")

        return compile(string.join(self.code,"\n"),"<code>","exec")

    def write(self,string):

        self.code.append(self.tab * self.level + string)



    def indent(self):

        self.level = self.level + 1

    def dedent(self):

        if self.level == 0:

            raise SyntaxError,"internal error in code generator"

        self.level = self.level - 1





c = CodeGeneratorBackend()



c.begin()

c.write("for i  in range(5):")

c.indent()

c.write("print 'code generation made easy!'")

c.dedent()

exec c.end()

result:

>>> ================================ RESTART ================================

>>> 

code generation made easy!

code generation made easy!

code generation made easy!

code generation made easy!

code generation made easy!

>>> 

 

Python还提供了execfile函数

一个从文件加载代码,编译代码,执行代码的快捷方式:

#builtin-execfile-example-1.py





execfile("hello.py")



def ExecFile(filename,locals=None,globals=None):

    exec compile(open(filename).read(),filename,"exec") in locals,globals



ExecFile("hello.py")

result:

>>> ================================ RESTART ================================

>>> 

hello again,and welcome to the show

hello again,and welcome to the show

>>> 

 

因为python在检查局部名称空间和模块名出呢个空间之前不会检查内建函数,所有有时候可能要显式引用__builtin__模块

下面例子重载了内建open函数,这时候要想使用原来的open函数,就需要脚本显式的指明模块名称:

#builtin-open-example-1.py





def open(filename,mode='rb'):

    impot __builtin__

    file = __builtin__.open(filename,mode)



    if file.read(5) not in ("GIF87","GIF89"):

        raise IOError,"not a GIF file"

    file.seek(0)



    return file



fp = open("333.gif")



print len(fp.read()),"bytes"

print len(fp.read()),"bytes"

 

打开文件最好用file

 

 

 

 

 

你可能感兴趣的:(python)