【1】在函数中参数前面加*表示传入函数的参数会存为元祖,元祖名称为*号后面的参数。
>>> def test(*arg):
for i in arg:
print (i)
>>> test(1,2,3)
1
2
3
【2】在函数中参数前面加**表示传入函数的参数会存为字典,字典名称为*号后面的参数。
>>> def test1(**arg):
for i in arg:
print (arg[i])
>>> test1(key1=1,key2=2)
1
2
【3】多种参数混合
>>> def test2(Bool,*arg1,**arg2):
print (Bool)
print (arg1)
print (arg2)
>>> test2(True,1,2,3,4,key1=1,key2=2)
True
(1, 2, 3, 4)
{'key1': 1, 'key2': 2}
【4】repr函数
>>> repr([1,2,3])
'[1, 2, 3]'
【5】创建新式类
__metaclass__ = type #表示新式类
class Person:
def SetName(self,name):
self.name=name
def GetName(self):
return self.name
def greet(self):
print ("hello:"+self.name)
def main():
A=Person()
B=Person()
A.SetName("A")
B.SetName("B")
print (A.GetName())
print (B.GetName())
A.greet()
B.greet()
if __name__ == "__main__":
main()
【6】类的继承(超类)
__metaclass__ = type
class Person:
def __init__(self,name=None):
self.name=name
def SetName(self,name):
self.name=name
def GetName(self):
return self.name
def greet(self):
print ("hello:"+self.name)
class Eat(Person):
def __init__(self):
#当子类不含有父类属性时,可以通过下面两种方式解决
#Person.__init__(self) #调用未绑定的超类构造方法
super(Eat,self).__init__() #使用super函数,推荐
def main():
A=Eat("A")
A.SetName("A")
print (A.GetName())
A.greet()
if __name__ == "__main__":
main()
注:当使用Person.__init__(self,name)时,子类需要def __init__(self,name),并且当调用子类时需要这样写A=Eat("A"),“A”表示name属性的值。
【7】访问私有方法
函数名称前面加__表示私有方法,只有类内部可以调用,但是理解了原理,其实外部也是可以访问的。在Python中私有方法被存储为_classname__fundation()的形式。因此在类外面访问时访问该名称即可,其中classname表示类名,function表示函数名称,类名前有一个下划线,函数名称前面有两个下划线。
【8】property函数,在下面的实例中这个函数创建了一个属性,其中访问器函数被用作参数(先取值然后是赋值),这个属性被命名为size
__metaclass__ = type
class Person:
def __init__(self):
self.width = 0
self.heigth = 0
def SetSize(self,size):
self.width, self.heigth = size
def GetSize(self):
return self.width, self.heigth
size = property(GetSize,SetSize)
def main():
A=Person()
A.heigth=10
A.width=15
print (A.size)
B=Person()
B.size=100,200
print (B.width," ",\
B.heigth," ",\
A.heigth)
if __name__ == "__main__":
main()
>>>
RESTART: C:/Users/Administrator/AppData/Local/Programs/Python/Python36/hanshu.py
(15, 10)
100 200 10
【9】静态方法和类方法
静态方法:定义时没有self参数,可被类本身直接调用。
类方法:定义时需要cls参数,可以直接用类的具体对象调用。
【10】类似于property的函数
__getattribute__(self,name):当特性name被访问时自动被调用(新式类中生效)
__getattr__(self,name):当特性name被访问并对象没有相应的特性时被自动调用。
__setattr__(self,name,value):当试图给name赋值时自动调用
__delattr__(self,name):当试图删除name特性时被自动调用
实例:
__metaclass__ = type
class Person:
def __init__(self):
self.width = 0
self.heigth = 0
def __setattr__(self,name,value):
if name == "size":
self.width, self.heigth = value
else:
self.__dict__[name] = value
def __getattr__(self,name):
if name == "size":
return self.width, self.heigth
else:
raise AttributeError
def main():
A = Person()
A.size = 100,200
print (A.size)
if __name__ == "__main__":
main()
【11】迭代器
具有next方法的对象
__metaclass__ = type
class Fibs:
def __init__(self):
self.a = 0
self.b = 1
def __next__(self): 注:在2版本中为: def next(self)
self.a, self.b = self.b, self.a+self.b
return self.a
def __iter__(self):
return self
def main():
A = Fibs()
for i in A:
if i < 10:
print (i)
else:
break
if __name__ == "__main__":
main()
【12】生成器
包含yield的函数称为生成器,生成器并不像return那样返回值,每次产生一个值就会被冻结,函数重新被唤醒时会从上一次停留的地方继续。
def flatten(nested):
for sublist in nested:
for element in sublist:
yield element
def main():
nested=[[1,2],[3],[4,5,6]] #注:这里都要加[]要不然会报错。
for num in flatten(nested):
print (num)
if __name__ == "__main__":
main()
【13】生成器的方法
send方法:开始生成器不能send非空值,因此要b.send(None)
在内部挂起生成器,yield现在作为表达式而不是语句使用,换句话说,当生成器重新运行的时候,yield方法返回一个值,也就是外部通过send方法发送的值,如果next方法被使用,那么yield方法返回None.
注:可以通过改变None实现生成器启动时使用send方法,也就是说改变None为你想要设定的值。
throw方法:用于在生成器内引发一个异常。
close方法:用于停止生成器。
>>> def repeater(value):
while True:
new = (yield value)
if new is not None: value = new
>>> b=repeater(100)
>>> b.send(None)
100
>>> b.send("hello")
'hello'
【14】八皇后问题
在一个N*N的棋盘中不允许两个皇后处于同一行同一对角线内。
state[1]=2表示第2行的皇后位于第3列,其他同上。
def conflict(state,nextX):
nextY = len(state)
for i in range(nextY):
#判断是否符合皇后摆放规则。
if abs(state[i]-nextX) in (0,nextY-i):
return True
return False
def queens(num=8,state=()):
for pos in range(num):
if not conflict(state,pos):
if len(state) == num-1:
yield (pos,)
else:
for result in queens(num,state + (pos,)):
yield (pos,) + result
def main():
print (list(queens(4)))
if __name__ == "__main__":
main()
【15】基本的序列和映射规则
__len__(self):这个方法应该返回集合中所包含项目的数量。对于序列来说,这就是元素的个数;对于映射来说则是键值对的数量,如果他返回0,对象会被当做一个布尔变量中的假值。
__getitem__(self,key):这个方法返回与所给键对应的值。
__setitem__(self,key):这个方法应该按一定的方式存储和key相关的value,这个value可以使用__getitem__获取。
__delitem__(self,key):这个方法在对一部分对象使用del语句时被调用,同时必须删除和键相关的键。
def checkIndex(key):
if not isinstance(key, (int)):raise TypeError
if key<0: raise IndexError
class ArithmeticSequence:
def __init__(self, start=0,step=1):
self.start=0
self.step=1
self.changed={}
def __getitem__(self, key):
checkIndex(key)
try: return self.changed[key]
except KeyError:
return self.start + self.step*key
def __setitem__(self,key,value):
checkIndex(key)
self.changed[key] = value
def __delitem__(self,key):
checkIndex(key)
try: self.changed.pop(key)
except KeyError:
print ("Error")
def main():
s = ArithmeticSequence()
print (s[4])
s[4] = 2
print (s[4])
del s[4]
print (s[4])
if __name__ == "__main__":
main()
【16】异常处理
import exceptions #导入异常模块,内建异常都可以在这个模块中找到
dir(exceptions) #列出所有异常
raise语句:用于抛出异常
try:
语句块
except (异常类型),e:
出现异常处理程序
finally:
不管是否发生异常都会执行的语句块。