一、反射
说反射之前先介绍一下__import__方法,这个和import导入模块的另一种方式
1. import commons 2. __import__(\'commons\')
如果是多层导入:
1. from list.text import commons 2. __import__(\' list.text.commons\',fromlist=True) #如果不加上fromlist=True,只会导入list目录
反射即想到4个内置函数分别为:getattr、hasattr、setattr、delattr 获取成员、检查成员、设置成员、删除成员下面逐一介绍先看例子:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
class Foo( object ): def __init__( self ): self .name = \'abc\' def func( self ): return \'ok\' obj = Foo() #获取成员 ret = getattr (obj, \'func\' ) #获取的是个对象 r = ret() print (r) #检查成员 ret = hasattr (obj, \'func\' ) #因为有func方法所以返回True print (ret) #设置成员 print (obj.name) #设置之前为:abc ret = setattr (obj, \'name\' , 19 ) print (obj.name) #设置之后为:19 #删除成员 print (obj.name) #abc delattr (obj, \'name\' ) print (obj.name) #报错 |
对于反射小节:
1.根据字符串的形式导入模块。 2.根据字符串的形式去对象(某个模块)中操作其成员
实例:基于反射实现类Web框架的路由系统
实现思路:规定用户输入格式 模块名/函数名 通过__import__的形式导入模块并通过 hasattr和getattr 检查并获取函数返回值。
二、面向对象
面向对象简称OOP,面向对象的程序设计把计算机程序视为一组对象的集合,而每个对象都可以接收其他对象发过来的消息,并处理这些消息,计算机程序的执行就是一系列消息在各个对象之间传递。
语法格式见下图:
关键字class 和函数def 是一样的。类名通常是大写开头的单词,定义号类后就可以创建实例如上图的类加()就相当于创建一个类的实例obj
- def Bar(self) 其中self 为形式参数
- 和实例化对象obj的内存地址相同
类的三大特性:封装、继承、多态
1、封装
面向对象编程的一个重要特点就是数据封装。例如:
class Foo: def fetch(self): print(self.beckend) #self 直接在对象里面取值 obj = Foo() obj.beckend = \'www.baidu.com\' #把beckend封装在对象里面 obj.fetch()
class Foo : \'\'\'构造方法\'\'\' def __init__(self,bk): self.backend = bk # 把obj对象的参数封装在 init 方法里 def fetch(self): print(self.backend) def add(self): print(self.backend) obj = Foo(\'www.xxx.com\') obj.fetch() obj.add()
通过代码我们看到__init__:称之为构造方法,需要注意__init__的第一个参数永远是self,表示的实例本身
封装的意义:当同一类型的方法具有相同的参数时,可以直接封装到对象里减少代码量。
使用场景把类当作模版,创建多个对象并且对象内封装的数据可以不同。
2、继承
当我们定义一个class的时候,可以从某个现有的class继承,新的class称为子类(Subclass),而被继承的class称为基类、父类或超类(Base class、Super class),有几点要注意:
- 继承要在子类加上父类的类名
- 子类和父类都有的方法,优先找子类的方法
- python里面可以继承多个类C#,java 不可以多继承
- 如果继承多个类,继承顺序为从左至右
例如下面的例子:
class Animals: def chi(self): print(self.Name + \' 吃\') def he(self): print(self.Name + \' 喝\') class Dog(Animals): def __init__(self,name): self.Name = name def jiao(self): print(self.Name + \' 叫\') xxoo =Dog(\'某某某\') xxoo.chi() xxoo.he() xxoo.jiao()
class Animals: def chi(self): print(self.Name +\' 吃\') def he(self): print(self.Name + \' 喝\') class Uncle: def du(self): print(self.Name + \' 赌\') class Dog(Animals,Uncle): def __init__(self,name): self.Name = name xxoo = Dog(\'某某某\') xxoo.chi() xxoo.du()
关于继承顺序需要注意例如 E继承(C,D) -->C继承(A)-->D继承(B) 如下图(python3):
class A: def f1(self): print(\'A\') class B: def f(self): print(\'B\') class C(A): def f(self): print(\'C\') class D(B): def f1(self): print(\'D\') class E(C,D): def f(self): print(\'E\') aa = E() aa.f1()
第二种查找顺序:E继承(C,D)-->C继承(A),D继承(B)-->A和B都继承(Boos) ,查找顺序如下(python3):
class Boos: def f1(self): print(\'Boos\') class A(Boos): def f(self): print(\'A\') class B(Boos): def f(self): print(\'B\') class C(A): def f(self): print(\'C\') class D(B): def f1(self): print(\'D\') class E(C,D): def f(self): print(\'E\') aa = E() aa.f1()
下面说下python27的查找顺序是什么那?
未继承object为经典类查找顺序--> 深度优先
3、多态
即多种形态....
补充:
关于继承如何执行父类的构造方法那?有两种方法如下代码:
class Annimal: def __init__(self): print(\'Annimal的构造方法\') self.ty = \'动物\' class Cat(Annimal): def __init__(self): print(\'Cat的构造方法\') self.n = \'猫\' super(Cat, self).__init__() #推荐用这种 # Annimal.__init__(self) #第二种方式 c = Cat()
查找源码的过程(self.xxxx(),从底层开始找)
三、成员
分别有静态字段、静态方法、类方法、特性、普通字段、普通方法、
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
|
class Provice: #静态字段 country = \'China\' def __init__( self ,name): #普通字段 self .name = name #普通方法 def show( self ): print ( \'show\' ) @staticmethod #静态方法 def xo(arg): print ( \'xo\' ) print (arg) @classmethod #类方法,必须要有个cls参数:自动传入类名 def xxoo( cls ): print ( \'xxoo\' , cls ) def start( self ): print ( \'start\' ) @property #特性 def end( self ): print ( \'end\' ) @end .setter def end( self ,values): print (values) self .name = values #也可以更改内存里的值 Provice.country #类访问静态字段 Provice.xo( \'alex\' ) #类访问静态方法 Provice.xxoo() #访问类方法 #获取特性值 obj = Provice( \'alex\' ) obj.end #设置特性值 obj1 = Provice( \'alex\' ) obj1.end = \'123\' print (obj1.name) #普通方法 obj1 = Provice( \'alex\' ) obj1.show() #普通字段 obj1 = Provice( \'alex\' ) print (obj1.name) |
成员小节:
- 自己去访问自己的成员,除了类中的方法
-
通过类访问的有:静态字段、静态方法、类方法
-
通过对象访问:普通字段、普通方法 、特性
静态字段:存在类中 ,静态字段存在的意:把对象里面重复的数据只在类里保存一份 静态方法 :没有self 可以传参数,调用的时候也需要传入参数 ,存在的意义:不需要创建对象,就可以访问此方法 ,为类而生 类方法:必须要有个cls参数:自动传入类名 特性 对象调用 、不能加参数,执行不用加括号 普通字段,存放在对象中 普通方法 存在的意义:普通方法如果要想被调用就需要创建self ,为对象而生
四、成员修饰符
公有成员:任何地方都能访问
私有成员:只有在类的内部才能访问,定义方式为命名时,前两个字符为下划线,如 "__test"
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
class Person: country = \'China\' #静态字段,属于公有成员 __planet = \'Earth\' #静态字段,属于私有成员 def __init__( self ,name): print ( \'Person build self.name\' ) self .name = name def say( self ): print ( \'The planet is %s\' % Person.__planet) #在类的内部访问私有静态字段 p1 = Person( \'Nothing\' ) p1.say() print (p1.country) #访问公有静态字段 print (p1.__planet) #访问私有静态字段 #执行结果: Person build self .name The planet is Earth #在类的内部可以访问 print (p1.__planet) China #外部可以访问公有静态字段 AttributeError: \'Person\' object has no attribute \'__planet\' #外部无法访问私有静态字段 |
小节:私有成员只能在类内部使用,其他的都不能使用包括继承的子类,也不是绝对 也可以通过访问,但是不推荐
对象._类名__字段名
类的特殊成员:
1
2
3
4
5
6
7
8
9
10
|
__doc__ 表示类的描述信息 __module__ 表示当前操作的对象在那个模块 __class__ 表示当前操作的对象的类是什么 __init__ 构造方法,通过类创建对象时,自动触发执行 __call__ 对象后面加括号,触发执行。 __dict__ 类或对象中的所有成员 __str__ 如果一个类中定义了__str__方法,那么在打印 对象 时,默认输出该方法的返回值。 __init__ 构造方法,通过类创建对象时,自动触发执行 __setitem__,__getitem__,__delitem__ 用于索引操作,如字典。分别表示获取、设置、删除数据 |
五、异常处理
异常即是一个事件,该事件会在程序执行过程中发生,影响了程序的正常执行。
一般情况下,在Python无法正常处理程序时就会发生一个异常。
异常是Python对象,表示一个错误。
当Python脚本发生异常时我们需要捕获处理它,否则程序会终止执行。
语法:
1
2
3
4
5
6
7
8
9
10
11
|
try : <语句> #运行别的代码 except <名字>: <语句> #如果在try部份引发了\'name\'异常 except <名字>,<数据>: <语句> #如果引发了\'name\'异常,获得附加的数据 else : <语句> #如果没有异常发生 finally : xxxx |
标准的异常有:
五、单例模式
单例模式,也叫单子模式,是一种常用的软件设计模式。在应用这个模式时,单例对象的类必须保证只有一个实例存在。许多时候整个系统只需要拥有一个的全局对象,这样有利于我们协调系统整体的行为。
用装饰器方式实现
def wapper(cls): instances = {} def inner(): if cls not in instances: instances[cls] = cls() return cls return inner @wapper def Foo(): pass f1 =Foo() f2 =Foo() print(f1 is f2)
静态方法实现:
class ConnectPool: __instatnce=None @staticmethod def get_instance(): if ConnectPool.__instatnce: return ConnectPool.__instatnce else: ConnectPool.__instatnce = ConnectPool() return ConnectPool.__instatnce obj =ConnectPool.get_instance() print(obj) obj1 =ConnectPool.get_instance() print(obj1)