1. 函数
1) 参数传递顺序,即调用者将参数传递给函数的顺序。python中有4种带参方式:
- fun1(a,b,c)
- fun2(a=1,b=2,c=3)
- fun3(*args)
- fun4(**kargs)
赋值过程为:
- 按顺序把传给args的实参赋值给对应的行参
- args = value 形式的实参赋值给行参
- 将多余出的即键值对行后的零散实参打包组成一个tuple传递给*args
- 将多余的key=value形式的实参打包正一个dicrionary传递给**kargs。
即上面4中带参方式的参数赋予顺序依次降低。
2) input([prompt]) 函数和 raw_input([prompt]) 函数基本类似,但是 input 可以接收一个Python表达式作为输入,并将运算结果返回;
3) lambda语句中,冒号前是参数,可以有多个,用逗号分割;冒号右边是返回值。lambda语句构建的是一个函数对象。
2. map, reduce, fiter 3个內建函数
1) map(function,sequence)
对sequence中的item依次执行function(item),将执行结果组成一个List返回。实现:
def map(func,seq): mapped_seq = [] for eachItem in seq: mapped_seq.append(func(eachItem)) return mapped_seq |
2) reduce(function,sequence)
对sequence中的item顺序迭代调用function。如果sequence的长度大于1,lambda表达式必须有两个参数(大于2个参数是不对的)。实现:
def reduce(bin_func,seq,initial=None): lseq = list(seq) if initial is None: res = lseq.pop(0) else: res = initial for eachItem in lseq: res = bin_func(res,eachItem) return res |
3) filter(function,sequence)
对sequence中的item依次执行function(item),将执行结果为True的item组成一个List/String/Tuple(取决于sequence的类型)返回。实现:
def filter(bool_func,seq): filtered_seq = [] for eachItem in seq: if bool_func(eachItem): filtered_seq.append(eachItem) return filtered_seq |
以上function都是lambda函数。
3. 作用域
1) python能够改变变量作用域的代码段是def、class、lamda。
2) python变量可以不需要申明直接定义,因为在定义时就能确定类型,未定义过的变量在使用时会报错。这一点在理解python语法中至关重要。
3) 在def内通过global可以申明全局变量,注意,这里是申明不是定义。
4. 可更改(mutable)与不可更改(immutable)对象
1) 在 python 中,strings, tuples, 和 numbers 是不可更改的对象,而 list,dict 等则是可以修改的对象。
- 不可变类型:变量赋值 a=5 后再赋值 a=10,这里实际是新生成一个 int 值对象 10,再让 a 指向它,而 5 被丢弃,不是改变a的值,相当于新生成了a。
- 可变类型:变量赋值 la=[1,2,3,4] 后再赋值 la[2]=5 则是将 list la 的第三个元素值更改,本身la没有变化,只是其内部的一部分值被修改了。
2) python中一切都是对象。当变量指向一个对象时,这个变量类似于C的指针或引用,python里面用引用计数来控制对象最后的析构。当变量名通过=符号赋给一个新值时,变量的地址也随之改变,而原来的值所在地址的内存由python负责回收处理。
5. 包,模块
1) 模块(module):每一个.py脚本定义一个模块,其中定义某个功能的函数或脚本,供其它.py脚本调用。
2) 包(package):多个.py脚本组织在一起,放在一个文件夹方便我们使用,即为一个包。文件夹下面必须有__init__.py文件。另外模块名称不能有横线,否则不能识别(自测发现)。
6. 编码
1) codecs.open和open打开文件的区别,前者可以选择打开文件时的解码方式,后者可能默认用gbk打开而导致无法解码。所以如果有中文,可以选择前者来打开文件。
2) 设置编码:
`import sys
reload(sys)
sys.setdefaultencoding('utf8')`
3) File 对象方法: file对象提供了操作文件的一系列方法;OS 对象方法: 提供了处理文件及目录的一系列方法
7. python方法
1) 父类与子类的构造函数执行情况:
如果子类定义了自己的__init__构造方法函数,当子类的实例对象被创建时,子类只会执行自己的__init__方法函数;如果子类未定义自己的构造方法函数,会沿着搜索树找到父类的构造方法函数去执行父类里的构造方法函数。
如果子类定义了自己的构造方法函数,且子类的构造方法函数内没有主动调用父类的构造方法函数,那父类的实例变量在子类不会在刚刚创建子类实例对象时出现了。
class aa: def __init__(self): self.x = 10 self.y = 12 def hello(self, x): return x + 1 class bb(aa): def __init__(self): aa.__init__(self) #如果注销此行,下边打印b.x和b.y将报错,未定义 通过类名字调用父类的构造方法函数 self.z = 14 a = aa() print a.x, a.y b = bb() print b.x, b.y |
2) python2.4 - 3.0继承体系中父类类必须继承某个类(并且这个继承链开始于object类),否则会报错。
3) python的方法分为静态方法、实例方法、类方法。类对象和实例都可以调用类方法和静态方法。静态方法和实例方法的区别主要体现在两个方面:
a. 在外部调用静态方法时,可以使用"类名.方法名"的方式,也可以使用"对象名.方法名"的方式。而实例方法只有后面这种方式。也就是说,调用静态方法可以无需创建对象。
b. 静态方法在访问本类的成员时,只允许访问静态成员(即静态成员变量和静态方法),而不允许访问实例成员变量和实例方法;实例方法则无此限制。
静态方法往往搭配静态变量使用,python中静态属性类似函数工具的作用,建议尽量少使用。
8. python类的变量
1) python的实例属性,区分了保护和私有属性。
_foo: 以单下划线开头的表示的是 protected 类型的变量,即保护类型只能允许其本身与子类进行访问,不能用于 from module import *。 __foo: 双下划线的表示的是私有类型(private)的变量, 只能是允许这个类本身进行访问。
在内部,python使用一种 name mangling 技术,将 __membername替换成 _classname__membername,所以你在外部使用原来的私有成员的名字时,会提示找不到。严格地说,私有方法在它们的类外是可以访问的,只是不容易 处理。在 Python 中没有什么是真正私有的。
python的继承,对于变量来说,是直接继承类属性,不继承实例属性,因此最好在构造函数中初始化定义所有实例属性,方便子类继承。
2) 类变量被类的所有对象在构造时共享,构造后对象拥有一份自己的类变量拷贝。通过classmethod的cls或staticmethod的类名方式,访问的是被所有实例对象共享的类变量。通过instance.var的方式访问的是对象自己拥有的类变量拷贝,其实算是实例变量了。 需要注意的是:对象在首次定义与类变量同名的实例变量前,该实例变量值与类变量保持同步,即它也会受其它改变该类变量的影响,定义之后才完全独立。
3) 对象变量只属于类构造的对象。通过instance.var的方式可以访问类的公有变量和保护变量,但不能访问私有变量。后者只能通过实例方法访问。
4) 类变量不同于C++的静态变量,区别在于一个类对象对类变量进行修改后,会不会影响其它类对象中这个变量的值。借用网上的一个总结:不管是C++还是python都大致分为3种变量/属性:
类属性(C++中叫静态变量,python中叫类属性)
实例属性(C++中叫成员变量,python中叫成员属性)
局部变量(C++中叫局部变量,python中叫局部变量)