-
同样的功能,StringIO 是纯Python代码编写的,而 cStringIO 部分函数是 C 写的,因此 cStringIO 运行速度更快。
利用ImportError错误,我们经常在Python中动态导入模块:
try: from cStringIO import StringIO except ImportError: from StringIO import StringIO
try 的作用是捕获错误,并在捕获到指定错误时执行 except 语句。
查看全部 -
如导入os包的path模块,为使用其中的isdir,isfile函数,可以有
import os
>>>os.path.isdir()
import os.path
>>>os.path.isdir()
from os import path
>>>os.path.isdir()
from os.path import isdir, isfile
>>>isdir()
from os.path import isdir as myisdir
>>>myisdir()
查看全部 -
将代码分拆放入多个py文件,同一个名字的变量不相互影响
同名模块放入两个不同包中则可不冲突,因为他们的完整模块名不同
查看全部 -
python中获取对象信息
拿到一个变量,除了用 isinstance() 判断它是否是某种类型的实例外,还有没有别的方法获取到更多的信息呢?
例如,已有定义:
class Person(object): def __init__(self, name, gender): self.name = name self.gender = gender class Student(Person): def __init__(self, name, gender, score): super(Student, self).__init__(name, gender) self.score = score def whoAmI(self): return 'I am a Student, my name is %s' % self.name
首先可以用 type() 函数获取变量的类型,它返回一个 Type 对象:
>>> type(123) <type 'int'> >>> s = Student('Bob', 'Male', 88) >>> type(s) <class '__main__.Student'>
其次,可以用 dir() 函数获取变量的所有属性:
>>> dir(123) # 整数也有很多属性... ['__abs__', '__add__', '__and__', '__class__', '__cmp__', ...] >>> dir(s) ['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'gender', 'name', 'score', 'whoAmI']
对于实例变量,dir()返回所有实例属性,包括`__class__`这类有特殊意义的属性。注意到方法`whoAmI`也是 s 的一个属性。
如何去掉`__xxx__`这类的特殊属性,只保留我们自己定义的属性?回顾一下filter()函数的用法。
dir()返回的属性是字符串列表,如果已知一个属性名称,要获取或者设置对象的属性,就需要用 getattr() 和 setattr( )函数了:
>>> getattr(s, 'name') # 获取name属性 'Bob' >>> setattr(s, 'name', 'Adam') # 设置新的name属性 >>> s.name 'Adam' >>> getattr(s, 'age') # 获取age属性,但是属性不存在,报错: Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: 'Student' object has no attribute 'age' >>> getattr(s, 'age', 20) # 获取age属性,如果属性不存在,就返回默认值20: 20
查看全部 -
import functools
>>> int2 = functools.partial(int, base=2)同def int2(x, base=2):
return int(x, base)查看全部 -
args为一个元组而kwags是一个字典类型。
这两个作为python的可变参数,也就是说args表示任何多个无名参数,然而kwags表示一个一个有着对应关系的关键字参数。
在使用的时候需要注意,*args要在**kwags之前,不然会发生语法错误。查看全部 -
得到 f 的函数名 f.__name__
得到当前时间 time.time() (要import time)
查看全部 -
python中多态
类具有继承关系,并且子类类型可以向上转型看做父类类型,如果我们从 Person 派生出 Student和Teacher ,并都写了一个 whoAmI() 方法:
class Person(object): def __init__(self, name, gender): self.name = name self.gender = gender def whoAmI(self): return 'I am a Person, my name is %s' % self.name class Student(Person): def __init__(self, name, gender, score): super(Student, self).__init__(name, gender) self.score = score def whoAmI(self): return 'I am a Student, my name is %s' % self.name class Teacher(Person): def __init__(self, name, gender, course): super(Teacher, self).__init__(name, gender) self.course = course def whoAmI(self): return 'I am a Teacher, my name is %s' % self.name
在一个函数中,如果我们接收一个变量 x,则无论该 x 是 Person、Student还是 Teacher,都可以正确打印出结果:
def who_am_i(x): print x.whoAmI() p = Person('Tim', 'Male') s = Student('Bob', 'Male', 88) t = Teacher('Alice', 'Female', 'English') who_am_i(p) who_am_i(s) who_am_i(t)
运行结果:
I am a Person, my name is Tim I am a Student, my name is Bob I am a Teacher, my name is Alice
这种行为称为多态。也就是说,方法调用将作用在 x 的实际类型上。s 是Student类型,它实际上拥有自己的 whoAmI()方法以及从 Person继承的 whoAmI方法,但调用 s.whoAmI()总是先查找它自身的定义,如果没有定义,则顺着继承链向上查找,直到在某个父类中找到为止。
由于Python是动态语言,所以,传递给函数 who_am_i(x)的参数 x 不一定是 Person 或 Person 的子类型。任何数据类型的实例都可以,只要它有一个whoAmI()的方法即可:
class Book(object): def whoAmI(self): return 'I am a book'
这是动态语言和静态语言(例如Java)最大的差别之一。动态语言调用实例方法,不检查类型,只要方法存在,参数正确,就可以调用。
任务
Python提供了open()函数来打开一个磁盘文件,并返回 File 对象。File对象有一个read()方法可以读取文件内容:
例如,从文件读取内容并解析为JSON结果:
import json f = open('/path/to/file.json', 'r') print json.load(f)
由于Python的动态特性,json.load()并不一定要从一个File对象读取内容。任何对象,只要有read()方法,就称为File-like Object,都可以传给json.load()。
请尝试编写一个File-like Object,把一个字符串 r'["Tim", "Bob", "Alice"]'包装成 File-like Object 并由 json.load() 解析。
?不会了怎么办
只要为Students类加上 read()方法,就变成了一个File-like Object。
参考代码:
import json class Students(object): def read(self): return r'["Tim", "Bob", "Alice"]' s = Students() print json.load(s)
查看全部 -
#调用 time 模块,用于时间的相关计算 import time #创建一个函数,用来计算用户调用函数前后的当前时间戳,再计算两个时间戳的差 def performance(f): #创建一个函数,打印出用户调用函数前后的时间,并计算时间差 #函数内的两个参数是保证任意个数的参数总是能够被正常调用 def print_time(*args,**wk): #打印 call performance() in 当前日期的时间,函数 time.strftime("%Y-%m-%d)将日期格式化成 年-月-日 的样子,而函数 time.localtime(time.time())是将时间格式化成 时-分-秒 的样子,由于没有给 time.localtime()函数赋予格式化的方法,选择了再一次调用 time.time()函数,获取当前计算机时间戳 print("call {}() in {}".format(f.__name__,time.strftime("%Y-%m-%d,time.localtime(time.time())))) #返回参数 f ,再用参数 f 调用(*args,**kw),保证函数调用时保证任意个数的参数总是能够被正常调用 return f(*args,**kw) #调用函数 print_time,计算打印用户调用函数的时间 return print_time #可以避免手动编写 f = decorate(f),简化代码 @performance #创建一个函数,用 reduce()函数计算 lambda 表达式调用 计算 f 参数返回的值的乘积 def factorial(n) return reduce(lambda x,y : x * y,range(1,n + 1)) #调用函数 factorial(n),并给 n 赋值 10,然后进行计算,返回结果 print(factorial(10))
查看全部 -
装饰器:定义了一个函数,想在运行时动态增加功能,又不想改动函数本身的代码
可利用高阶函数接收一个函数,对其包装,然后返回一个新函数
查看全部 -
#Python的 decorator 本质上就是一个高阶函数,它接收一个函数作为参数,然后,返回一个新函数。使用 decorator 用Python提供的 @ 语法,这样可以避免手动编写 f = decorate(f) 这样的代码。 #先导入 time 库 import time #创建一个函数,用来打印出当前函数调用的时间 def performance(f): #再创建一个函数,计算函数调用前后的时间戳,计算时间戳到时间差 #新函数 fn(*args,**kw) 里面的两个参数是用来保证任意个数的参数都能被正常调用 def fn(*args,**kw): #首次获取当前计算机的时间戳 t1 = time.time() #给 函数 fn(*args,**kw)的两个参数赋值 r = f(*args,**kw) #第二次获取时间戳 t2 = time.time() #打印 call performance() in 当前日期的时间 #第一个中括号 {} 里面是 f.__name__,它用参数来格式化当前函数的名字 #第二个中括号 {} 里面是 (t2 -t1) ,用第二次获取的时间减去第一次获取的时间 print("call {}() in {}".format(f.__name__,(t2 - t1))) #将计算结果返回 r 变量 return r #将本函数的计算方法存储起来,返回 fn() 函数,等到调用的时候再直接调用 factorial()函数就可以了 return fn #可以避免手动编写 f = decorate(f),简化代码 @performance #创建一个函数,因为 @performance 的语法,可以将 performance()函数的 r 返回值调用,然后进行计算 def factorial(n): #利用 lambda 表达式 调用 reduce()函数计算参数 x 和 y 的乘积,x 和 y 的值是 range()函数里的赋值 return reduce(lambda x,y : x * y,range(1,n + 1)) #直接调用 factorial()函数,赋值 n 为 10,并打印计算结果 print(factorial(10)) """ 本例题的用意在于将一个函数闭包,再嵌套在另一个函数里调用,也就是说,可以将函数调用的方法隐藏起来 """
查看全部 -
高阶函数可以接收函数做参数,有些时候,我们不需要显式地定义函数,直接传入匿名函数更方便
关键字lambda 表示匿名函数,冒号前面的 x 表示函数参数
>>> map(lambda x: x * x, [1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> myabs = lambda x: -x if x < 0 else x
匿名函数有个限制,就是只能有一个表达式,不写return,返回值就是该表达式的结果
查看全部 -
# lambda() 函数是一个匿名函数 print(filter(lambda s : s and len(s.strip()) > 0 ,['test', None, '', 'str', ' ', 'END']) """ 这个表达式的作用是 利用 filter()函数过滤掉 参数 s 中不符合 条件 s and len(s.strip()) > 0 的值,而 strip()函数的作用是将 参数 s 内的 ["",\n,\t,\r] 删除,默认是将两端的空格删除,最后的列表就是 filter()函数的过滤内容
查看全部 -
python中判断类型
函数isinstance()可以判断一个变量的类型,既可以用在Python内置的数据类型如str、list、dict,也可以用在我们自定义的类,它们本质上都是数据类型。
假设有如下的 Person、Student 和 Teacher 的定义及继承关系如下:
class Person(object): def __init__(self, name, gender): self.name = name self.gender = gender class Student(Person): def __init__(self, name, gender, score): super(Student, self).__init__(name, gender) self.score = score class Teacher(Person): def __init__(self, name, gender, course): super(Teacher, self).__init__(name, gender) self.course = course p = Person('Tim', 'Male') s = Student('Bob', 'Male', 88) t = Teacher('Alice', 'Female', 'English')
当我们拿到变量 p、s、t 时,可以使用 isinstance 判断类型:
>>> isinstance(p, Person) True # p是Person类型 >>> isinstance(p, Student) False # p不是Student类型 >>> isinstance(p, Teacher) False # p不是Teacher类型
这说明在继承链上,一个父类的实例不能是子类类型,因为子类比父类多了一些属性和方法。
我们再考察 s :
>>> isinstance(s, Person) True # s是Person类型 >>> isinstance(s, Student) True # s是Student类型 >>> isinstance(s, Teacher) False # s不是Teacher类型
s 是Student类型,不是Teacher类型,这很容易理解。但是,s 也是Person类型,因为Student继承自Person,虽然它比Person多了一些属性和方法,但是,把 s 看成Person的实例也是可以的。
这说明在一条继承链上,一个实例可以看成它本身的类型,也可以看成它父类的类型。
查看全部 -
在函数内部定义的函数和外部定义的函数是一样的,只是他们无法被外部访问,可防止其他代码调用
内层函数引用了外层函数的变量(参数也算变量),然后返回内层函数的情况,称为闭包(Closure)。
闭包的特点是返回的函数还引用了外层函数的局部变量,所以,要正确使用闭包,就要确保引用的局部变量在函数返回后不能变。即返回函数不要引用任何循环变量,或者后续会发生变化的变量。
查看全部
举报