Python学习第十三天——装饰器和继承
2018-03-12 18:23
405 查看
上周回顾
#关键字参数**kwargs - 根据参数名来决定如何执行 def say_hello(*args, **kwargs): print(args)#相当于元组(可变参数) print(kwargs)#相当于字典(关键字参数) say_hello(1, 2, 'hello', name='骆昊', age=38)
#命名关键参数 #*之前参数名可写可不写,*之后参数名必须写 def foo(a, b, c,*, name, age): print(a + b + c) print(name ,':', age) foo(1, 2, 3, name='Hao', age=38) foo(a=1, b=2, c=3, name='hao', age=38) #foo(1, 2, 3, 'HAO', 38) 错误写法
def say_hello(**kwargs): if 'name' in kwargs: print('你好,%s!'% kwargs['name']) elif 'age' in kwargs: age = kwargs['age'] if age <= 16: print('你是一个小屁孩') else: print('你是一个成年人') else: print('请提供个人信息') say_hello(name='骆昊', age=38) param = {'name':'王大锤', 'age':16, 'tel':1234556} #say_hello(param) 不能直接将字典传进去 #如果希望将一个字典作为关键字参数传入,需要在参数前加** say_hello(**param)
def my_sum(*arg): pass mylist = [1, 23, 3] #如果希望将一个列表或元组作为可变参数传入,需要在参数前加* my_sum(*mylist)#传入列表时,在参数前加一个*
decorator - 装饰器/包装器
#高阶函数 - f(g(x)) def my_sum(my_list): total = 0 for val in my_list: total += val return total def my_mul(my_list): total = 1 for val in my_list: total *= val return total #可以看出这两个函数有很多重复代码,应该可以更优化 my_list = [1, 3, 5, 7, 9] print(my_sum(my_list)) print(my_mul(my_list))
编程理念
高内聚,低耦合high cohesion low coupling
高内聚 一个好的函数应该只做好一件事
低耦合 不要让代码跟特定的运行环境耦合在一起
四人帮设计模式
#通过向函数中传入函数 可以写出更通用的代码 #calc函数中的第二个参数是另一个函数,它代表了一个二元运算 #这样calc函数就不需要跟某一种特定的二元运算耦合在一起 #所以calc函数变得通用性更强,可以由传入的第二个参数决定到底做什么 def calc(my_list, op): total = my_list[0] for index in range(1, len(my_list)): total = op(total, my_list[index]) return total def add(x, y): return x + y def mul(x, y): return x * y my_list = [1, 3, 5, 7, 9] print(calc(my_list, add)) print(calc(my_list, mul))
def bar(): def foo(a, b, c,*, name, age): print(a + b + c) print(name ,':', age) return foo #foo()不能直接访问foo()函数了 x = bar()
装饰器/包装器
def record(fn):#fn是被装饰的函数 def wrapper(*args, **kwargs): print('准备执行%s函数'% fn.__name__) print(args) print(kwargs) #此行代码在执行被装饰的函数 #在这行代码的前后我们可以附加其他的代码 #这些代码可以让我们在执行函数时做一些额外的工作 val = fn(*args, **kwargs) print('%s函数执行完成'% fn.__name__) print('返回了%d'%val) #返回被装饰的函数的执行结果 return val return wrapper #通过装饰器修饰f函数 让f函数在执行过程中可以做更多额外的操作 @record #装饰器语法 def f(n): if n == 0 or n == 1: return 1 return n * f(n - 1) print(f(5))
def record(fn): def wrapper(*args , **kwargs): print('hello,world') val = fn(*args, **kwargs) return val return wrapper @record def foo(x, y): return x + y print(foo(1, 3))
hello,world 4
重点 在类中,里面的方法想要调用已经写好的方法,用self.方法名来实现
class Ultraman(object): __shots__ = ('_name', '_hp', '_mp')#限定了这个类只能绑定这三个属性 def __init__(self, name, hp=500, mp=100): self._name = name self._hp = hp self._mp = mp @property # 属性包装器,可以在下面直接通过对象.name 来访问self._name def name(self): return self._name #属性访问器 @property #如果没有对此对象使用包装器,下面不能使用修改器 def hp(self): return self._hp #属性修改器 @hp.setter # 修改器,可以在下面通过对象.hp来进行访问和修改 def hp(self, hp): self._hp = hp if hp >= 0 else 0 #属性删除器 @hp.deleter def hp(self): del self._hp ul = Ultraman('AA') print(ul.name) #ul.app = True 如果在类里没有限定的话,这个在下面加属性的行为是被允许的
AA
raise ValueError('输入的值无效') #引发值错误
--------------------------------------------------------------------------- ValueError Traceback (most recent call last) <ipython-input-9-69992949a9b6> in <module>() ----> 1 raise ValueError('输入的值无效') #引发值错误 ValueError: 输入的值无效
import math class Point(object): """点""" def __init__(self, x=0, y=0): """ 构造器 :param x: 点的橫坐标 :param y: 点的纵坐标 """ self._x = x self._y = y @property def x(self): return self._x @property def y(self): return self._y def move_to(self, x, y): self._x = x self._y = y def move_by(self, dx, dy): self._x += dx self._y += dy def distance_to(self, other): dx = self._x - other.x dy = self._y - other.y return math.sqrt(dx ** 2 + dy ** 2) class Line(object): def __init__(self, start, end): self._start = start self._end = end @property def length(self): return self._start.distance_to(self._end) # 线 段上有两个点 - has - a - 关联 # 人使用了房子 -use-a - 依赖 # 学生是人 -is-a - 继承 def main(): p1 = Point(3, 5) p2 = Point() l1 =Line(p1,p2) print(l1.length) if __name__ == '__main__': main()
继承
#继承-从已经有的类创建新类的过程 #提供继承信息的称为父类(超类/基类) #得到继承信息的称为子类(派生类/衍生类) #通过继承我们将子类中的重复代码抽取到父类中 #子类通过继承并复用这些代码来减少重复代码的编写 #将来如果要维护子类的公共代码只需要在父类中进行操作即可 class Person(object): def __init__(self, name, age): self.name = name self.age = age @property def name(self): return self._name @property def age(self): return self._age @age.setter def age(self, age): self._age = age class Student(Person): b364 def __init__(self, name, age, grade): super().__init__(name, age) #通过这个方法可以实现将父类的参数引用过来 self._grade = grade def study(self, course): print('%s正在学习%s'% (self.name, course)) def watch_av(self): if self.age >= 18: print('%s,正在观看岛国爱情动作片'% self.name) else: print('%s, 我们推荐你观看熊出没'% self.name) def watch_av(self): print('%s正在看片' % (self._name)) class Teacher(Person): def __init__(self, name, age, title): super().__init__(name, age) self._title = title @property def title(self): return self._title @title.setter def title(self, title): self._title = title def teach(self, course): print('%s%s正在教%s' % (self._name, self._title, course)) def main(): pass if __name__ == '__main__': main()
""" 思考题 工资结算系统 给员工信息计算出工资 部门经理 15000月薪 程序员 150元/小时 销售员 1200 + 销售额5%的提成 """
class staff(object): def __init__(self, name, salary): self._name = name self._salary = salary class DepartmentManager(staff): def __init__(self, name, salary=15000): super().__init__(name, salary) @property def d_salary(self): return '%s的工资是%s' % (self._name, str(self._salary)) class Programmer(staff): def __init__(self, name, salary, man_hours): super().__init__(name, salary) self._man_hours = man_hours @property def p_salary(self): return '%s的工资是%s' % (self._name, str(self._man_hours * self._salary)) class Salesman(staff): def __init__(self, name, salary, sale): super().__init__(name, salary) self._sale = sale @property def s_salary(self): return '%s的工资是%s' % (self._name, str(self._salary + self._sale * 0.05)) def main(): d1 = DepartmentManager('唐', 15000 ) g1 = Programmer('王', 150, 240) s1 = Salesman('李', 1200, 200000 ) print(d1.d_salary) print(g1.p_salary) print(s1.s_salary) if __name__ == '__main__': main()
唐的工资是15000 王的工资是36000 李的工资是11200.0
相关文章推荐
- python学习第十三天 -模块和包
- python装饰器的学习笔记二
- python学习小结5:封装、继承、多态
- python深入学习笔记5-装饰器
- Python装饰器学习(九步入门)
- python学习笔记四 迭代器,生成器,装饰器(基础篇)
- Python装饰器学习(九步入门)
- python装饰器学习总结
- Python学习笔记8-类的继承 、深度优先、广度优先
- python装饰器学习
- Python接口与类继承学习-pybatis的准备阶段(九)
- Python装饰器学习(九步入门)
- Python装饰器学习
- Python第九天 面向对象 类定义 类的属性 类的方法 内部类 垃圾回收机制 类的继承 装饰器
- Python学习笔记(11):类的继承
- python学习系列之python装饰器基础(3)---装饰器实现用户登录验证
- 我的python学习--第十三天
- Python学习09:继承与多重继承
- python类学习以及mro--多继承属性查找机制
- python学习04--继承