函数式编程
高阶函数:一个函数可以接收另一个函数作为参数
map() : map(function, Iterrable) :将传入的函数一次作用于序列的每个元素上,并将结果作为新的Iterator返回
# 实现,f(x) = x2, 作用于l = [1,2,3,4] def func(x): return x*x L = reduce(func, [1,2,3,4]) print(L)
reduce() :reduce把一个函数作用在一个序列上,该函数必须接收两个参数,reduce把结果继续和序列的下一个元素做累积计算
# 实现[1,2,3,4,5]Z转换为12345 def func(x,y): return x×10 + y L = reduce(func, [1,2,3,4,5,6]) print(L)
filter() : filte把传入的函数作用于每个元素,根据返回值true/false 过滤元素
# 将序列中的空字符串删除 def not_empty(s): return s and s.strip() # print(list(filter(not_empty, ['A', '', 'B', None, 'C', ' '])))
# 使用filter筛选出回数 def is_palindrome(n): return str(n) == str(n)[::-1] output = filter(is_palindrome, range(1, 1000)) print('1~1000:', list(output))
sorted():可接收一个key函数实现自定义的排序,将函数作用于每一个元素,按key函数返回的结果进行排序
print(sorted([36, -25, -68, 79], key=abs)) print(sorted(['bob', 'about','Zoo'])) print(sorted(['bob', 'about','Zoo'], key=str.lower)) >>> [-25, 36, -68, 79] ['Zoo', 'about', 'bob'] ['about', 'bob', 'Zoo']
L = [('Bob', 75), ('Adam', 92), ('Bart', 66), ('Lisa', 88)] def by_name(t): return t[0].lower() def by_score(t): return t[1] print(sorted(L, key=by_score, reverse=True)) print(sorted(L, key =by_name ))
返回函数:闭包,将函数作为结果值返回(返回函数名)
# 计数器,每次调用counterA()时,+1 def createCounter(): f = [0] def counter(): f[0] = f[0] + 1 return f[0] return counter counterA = createCounter() print(counterA(),counterA())
匿名函数:lambda x:(x为函数参数)不需要显示定义函数,使用表达式的结果作为返回值
L = list(filter(lambda x: x %2 ==1 , range(1,20))) print(L)
装饰器:调用函数时,不修改函数定义,但调用时动态增加功能的方式
# 装饰器函数 def log(func): @functools.wraps(func) def wrapper(*args, **kw): print(func.__name__) return func(*args, **kw) return wrapper @log #将装饰器装饰在now函数上 def now(): print('2015-3-25') now() print(now.__name__)
当装饰函数需要传入参数时
# 当装饰器函数需要传入参数时: def log(text): def derectorA(func): @functools.wraps(func) def wrapper(*args, **kw): print(func.__name__) return func(*args, **kw) return wrapper return derectorA @log('execute') def now(): print('2021-6-23') now() print(now.__name__)
例:设计一个装饰器,打开多装饰函数的执行时间
# 设计decoratoe,打印函数的执行时间 import time def metric(fn): @functools.wraps(fn) # 作用是让所装饰的函数名称等属性复制到wrapper上,(保证依赖函数签名的代码执行正常) def wrapper(*args, **kw): t1 = time.time() print(t1) fn(*args, **kw) t2 = time.time() print(t2) print('%s executed in %s ms' % (fn.__name__, t2-t1)) return fn(*args, **kw) return wrapper # 测试 @metric def fast(x, y): time.sleep(0.0012) return x + y @metric def slow(x, y, z): time.sleep(0.1234) return x * y * z f = fast(11, 22) s = slow(11, 22, 33)
偏函数:将函数的某些参数固定,返回一个新的函数(与默认参数的作用一致,降低函数调用的难度)
# 实现转换二进制字符串,int(x, base =2)[应用于批量转换二进制字符串] int2 = functools.partial(int, base = 2) #偏函数 print(int2('100011')) print(map(int2, ['110', '100', '001']))
面向对象编程
""" 类属性实例属性实例方法类方法静态方法 """ class ClassA(): name = '类属性名称' # 类属性,类访问,所有实例也均可访问 # 构造函数,可写可不写,当需要给所有实例绑定必须的属性时,可编写加上必须绑定的属性 def __init__(self, Test_name): self.test_name = Test_name # 实例属性 # 实例方法,由实例调用 def instance_func(self): print("调用实例方法") # 类方法,由类调用也可由实例调用 @classmethod def class_func(cls): print("调用类方法") # 静态方法,可被类和实例调用 @staticmethod def satic_func(): print("调用静态方法") test = ClassA("测试名称") print(test.test_name) # 实例调用实例名称 print(ClassA.name) # 类调用类属性 print(test.name) # 实例调用类属性 test.instance_func() test.class_func() ClassA.class_func() test.satic_func() ClassA.satic_func()
访问限制:限制外部访问内部属性,可通过方法访问获取属性,修改属性时同样有一样的范围限制,不可随意修改
# coding=utf-8 # 访问限制,不允许访问name属性,修改score属性时,限制修改范围为:60-100 class Student(object): def __init__(self, name, score): self.__name = name # 私有属性,外部代码不可随意修改对象内部的状态 self.__score = score # 允许外部代码获取属性及一定程度范围的修改 def get__score(self): return self.__score def set__score(self, score): if 60 <= score <= 100: self.__score = score else: raise ValueError('error score') s1 = Student('byy', 110) print(s1.get__score()) # 通过使用方法获取属性 print(s1.set__score(99)) # 通过调用方法修改属性 print(s1.__score) # 属性名称前加__,变为私有变量,只有内部可以访问,外部不能访问
继承和多态
class Animal(object): def run(self): print('Animal is running') class Dog(Animal): #继承Animal类 def run(self): # 子类的run覆盖父类run方法 print('dog is running') class Tortoise(object): def run(self): print("Tortoise is running") dog = Dog() dog.run() # 调用子类的run方法, def run_teice(am): # 传入实例,该实例有run方法 am.run() run_teice(Dog()) run_teice(Tortoise())
获取对象信息
判断对象的类型 isinstance(dog, Dog)
获取一个对象的所有属性和方法:dir()
通过后面的方法配合可操作对象的状态:getattr()、setattr()、hasattr()
class Myobject(): def __init__(self): self.x = 9 def power(self): print('hh') obj = Myobject() m = 'abc' print(dir(m)) # 获取对象的所有属性和方法 print(dir(obj)) print(hasattr(obj, 'x')) # 判断是否有属性x print(setattr(obj, 'y', 16)) # 为对象设置属性y print(getattr(obj, 'y')) # 获取属性y
# 每创建一个实例, count值加一 class Student(object): count = 0 def __init__(self, name): self.name = name Student.count = Student.count+1 S1 = Student('S1') S2 = Student('S2') print(Student.count) print(S1.count)
__slots__ : 限制实例属性的绑定
定义类并创建了类的实例后,可动态的给实例添加任何属性和方法,
class Student(object): pass def set_age(self,age): self.age =age # 可通过self来给实例绑定属性 S1 = Student() S1.name = 'S1' # 可任意给实例绑定属性 from types import MethodType # 给S1实例单独绑定方法 S1.set_age = MethodType(set_age, S1) S1.set_age(12) print(S1.age) print(S1.name)
限制实例可以绑定的属性,__slots__ (__slots只对当前类的实例起作用,对继承的子类不起作用)
# 限制实例属性的绑定 class Student(object): __slots__ = ('name', 'age') # 使用tuple定义允许绑定的属性名称 S1 = Student() S1.name = 'S1' S1.score = 99 # 不允许绑定该属性
@property : 装饰器负责将方法变成属性去调用
调用属性的方式不变的同时,增加对属性的检查(之前通过get_score, set_score实现对属性的检查,但调用的是方法,因此@property的作用为将方法变成属性去调用)
getter : 只读属性 setter:赋值属性, 未调用setter则为一个只读属性
class Screen(object): # 定义一个可修改值属性width和只读属性resolution @property def width(self): return self._width @property def resolution(self): # 定义resolution]为只读属性 return 'resolution' @width.setter # width属性 def width(self,wid_value): if not isinstance(wid_value, int): raise TypeError('width must be integer') if wid_value<0: raise ValueError('width must between 1~100') self._width = wid_value sc = Screen() sc.width = 99 print(sc.resolution )