2.1.python第二章:面向对象编程

it2023-10-05  79

[1. 私有属性](#1-私有属性)[2. 类属性和实例属性](#2-类属性和实例属性)[3. 继承](#3-继承) [4. 多态](#4-多态)[5. 类型检查](#5-类型检查)[6. 常用设计模式](#6-常用设计模式)[7. 异常处理](#7-异常处理)[8. 调用栈](#8-调用栈) [9. 模块](#9-模块)

1. 私有属性

用两个下划线表示私有属性,如:self.__name = name python没有真正的私有,把私有该名称_Student__name依旧可以访问:print(xiaobai._Student__name)

2. 类属性和实例属性

class Student(): def __init__(self, name, age): # 实例属性,必须通过初始化或者实例化对象,通过对象访问 self.__name = name # 加两个下划线表示私有属性 self.__age = age class Student2(): # 类属性,不需要实例化对象,直接通过类名访问,公共 name = 'student' # 不要对实例属性和类属性使用相同的名字,因为相同名称的实例属性将屏蔽掉类属性,但是当删除实例属性后,再使用相同的名称,访问到的将是类属性。

3. 继承

class Animal(object): def run(self): print('Animal is running') class Dog(Animal): def run(self): super().run() # 调用父类的run方法 print('Dog is running') def eat(self): print('Dog eat meat')

4. 多态

若某个实例对象是子类的实例对象,那么这个实例对象既可看成子类实例对象也可看做父类实例对象

a = Animal() d = Dog() print(isinstance(a, Animal)) # True print(isinstance(d, Dog)) # True print(isinstance(d, Animal)) # True # 调用此方法需要传入Animal对象或Animal子类对象 def run_twice(Animal): Animal.run()

5. 类型检查

type() isinstance() dir()获得一个对象的所有属性和方法

import types # 类型判断 print(type(run_twice) == types.FunctionType)# 判断是不是方法 print(type(abs) == types.BuiltinFunctionType)# 判断是不是内置方法 class MyObject(): def __init__(self): self.x = 9 def power(self): return self.x * self.x obj = MyObject() # 动态检测对象有什么属性,动态设置对象属性,动态取值(不推荐使用) # obj有属性x吗? print(hasattr(obj,'x')) # 设置一个属性y setattr(obj,'y',19) print(getattr(obj,'y'))

6. 常用设计模式

生成器:循环过程中需要不断推算出后续的元素,这样不必创建完整的list,这种一边循环以便计算的机制,称为生成器 生成器的两种定义方式: (1)列表生成式 (2)带yield的generator function # python内置用于创建list的生成式 # 快速将字典内容转变为list dic1 = {'x': 'A', 'y': 'B', 'z': 'C'} list1 = [k + '=' + v for k,v in dic1.items()] # ['x=A', 'y=B', 'z=C'] list1 = [str(k) + '*' + str(k) for k in range(1, 11)] list1 = [m+n for m in'abc' for n in '123'] # ['a1', 'a2', 'a3', 'b1', 'b2', 'b3', 'c1', 'c2', 'c3'] list1 = [m+n for m in'a.b.c' for n in '123' if m != '.'] # ['a1', 'a2', 'a3', 'b1', 'b2', 'b3', 'c1', 'c2', 'c3'] print(list1) list1 = [x * x for x in range(4)] print(list1) # [0, 1, 4, 9] g = (x * x for x in range(4)) print(g) # <generator object <genexpr> at 0x0000000001DE5AC8> for n in g: print(n, end=' ') # 0 1 4 9 # g保存的是一个算法,每次调用next的时候会计算出g的下一个元素值,最后取不出元素时会抛出一个异常 # 斐波那契数列 1,1,2,3,5,8 def fib(max): n, a, b = 0, 0, 1 while n < max: print(b) a, b = b, a+b n = n + 1 return 'done' def fib(max): n, a, b = 0, 0, 1 while n < max: yield b a, b = b, a+b n = n + 1 return 'done' # 输出关键字换成yield g = fib(6) for n in g: print(n) 函数的高级应用 (1) 函数即变量 变量可以指向函数函数名也是变量传入函数函数本身也可以赋值给变量 print(abs(-10)) # 10 f = abs print(f) # <built-in function abs> print(f(-10)) # 10 # abs = 10 # abs(-10) # abs函数被覆盖,报错'int' object is not callable def add(x, y, f): return f(x)+f(y) # 把函数当做参数传给其他函数 print(add(8, -3, abs)) # 11

(2)Map函数

map()函数接收两个参数,一个是函数,一个是Iterable map 将传入的函数以作用到序列的每个元素,并把结果作为新的Iterable返回

def func(x): return x * x list1 = [1, 2, 3, 4, 5] m = map(func, list1) print(m)# <map object at 0x0000000002450A08> print(list(m))# [1, 4, 9, 16, 25] print(list(map(str, list1)))#['1', '2', '3', '4', '5']

(3)Reduce函数

reduce 把一个函数作用在一个序列[x1,x2,x3,···]上,reduce把结果继续和序列的下一个元素做累计计算 reduce(f,[x1,x2,x3,x4])=f(f(f(x1,x2),x3),x4)

# 把序列[1,2,3,4,5,6]变换成整数123456 from functools import reduce def f(x, y): return x * 10 + y print(reduce(f,[1, 2, 3, 4, 5, 6]))

reduce+map综合应用:

def char2num(s): dict1 = {'0':0,'1':1,'2':2,'3':3,'4':4,'5':5,'6':6,'7':7,'8':8,'9':9} return dict1[s] def f(x, y): return x * 10 + y s1 = '5678' print(reduce(f, map(char2num, s1)))

(4)匿名函数

在函数1中定义函数2,该函数2只能在函数1中调用

from functools import reduce DICT1 = {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9} # 常量,放在公共区域 def str2int(s): def f(x, y): return x * 10 + y def char2num(s): return DICT1[s] return reduce(f, map(char2num, s)) print(str2int('4567')) 再进行优化:使用lambda def str2int(s): def char2num(s): return DICT1[s] return reduce(lambda x, y: x * 10 + y, map(char2num, s)) print(str2int('4567'))

lambda的一般形式是关键字lambda后面跟一个或多个参数,紧跟一个冒号,以后是一个表达式。lambda是一个表达式而不是一个语句。它能够出现在Python语法不允许def出现的地方。作为表达式,lambda返回一个值(即一个新的函数)

1、一般的形式     f = lambda x, y, z :x+y+z     print f(1,2,3) #6 2lambda用来编写跳转表(jump table)行为的列表或者字典 L = [lambda x: x+2, lambda x: x*2, lambda x: x**2] print "L=", L[0](1), L[1](2), L[2](3) #L = 3 4 9 D = {"d1": lambda x: x**1, "d2": lambda x: x**2, "d3": lambda x: x**3 } print "D=", D["d1"](2), D["d2"](2), D["d3"](2) # D= 2 4 8

(5)装饰器

在代码运行期间动态增加给功能的方式,成为装饰器

1. 调用方式一 import datetime def now(): print(datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')) # 装饰器 以一个函数作为参数,并返回一个函数 def log(f): def write_log(*args, **kw): with open('./a.txt', 'w')as file1: file1.write(f.__name__) print('写入日志成功,函数名字是:%s' % f.__name__) return f(*args, **kw) # 此处now函数被调用 return write_log ff = log(now) # ff是return回来的write_log函数,但是,此时并没有被调用 ff()# 调用write_log函数 print(ff.__name__)# write_log 2.调用方式二,python 提供的简单装饰器调用:关键字@ import datetime # 装饰器 以一个函数作为参数,并返回一个函数 def log(f): ······· ······· @ log def now(): ······ ······ now() 3. python提供的内置装饰器 @property @setter # 加上装饰器,方法变成属性 class Student2(): def __init__(self,age): self.__age = age @property def age(self): return self.__age @age.setter def age(self, value): self.__age = value stu2 = Student2(23) stu2.age = 58 print(stu2.age) # 58

7. 异常处理

try: ··· except ValueError as e: ··· except ZeroDivisionError as e: ··· finally: ··· Raise 抛出异常 自定义异常,所有异常都继承于BaseException try: print('try···') a = 100/0 print('result:', a) except ValueError as e: print('ValuError',e) except ZeroDivisionError as e: print('ZeroDivisionError', e) #raise 把错误抛到上一层,让上一层处理 else: print('unkown error') finally: print('不好意思出错了...') print('end')

8. 调用栈

def f(s): return 100/int(s) def bar(s): return f(s)*2 # 在python中如果py是单独运行,那么__name__= '__main__',如果py文件被其它模块引入调用时就不等于 if __name__ == '__main__': '''一般写测试代码''' bar('0') # 报错,返回一个调用栈 # Traceback (most recent call last): # File "...", line 259, in <module> # bar('0') # File "...", line 255, in bar # return f(s)*2 # File "...", line 253, in f # return 100/int(s) # ZeroDivisionError: division by zero

9. 模块

#!/usr/bin/env python3 用于linux系统下使py文件可以执行 # -*- coding:ytf-8 -*- 说明编码 '说明模块用途的地方' __author__ = 'xqy'
最新回复(0)