首先我们应该知道,python在设计之初就已经是一门面向对象的语言,所以说python中创建一个类和对象是很容易的。
面向对象的技术简介
- 类(class):用来描述具有相同的属性和方法的对象的集合。它定义了该集合中每个对象所共有的属性和方法,对象是类的实例。
- 类变量:类变量在整个实例化的对象中是公用的。类变量定义在类中且在函数体之外。类变量通常不做实例变量使用。
- 数据成员:类变量或者实例变量用于处理类及实例对象的相关数据。
- 方法重写:如果从父类继承的方法不能够满足子类的需求,可以对其进行改写,这个过程的方法叫覆盖,也称方法的重写。
- 实例变量:定义在方法中的变量,只用于当前实例中的类。
- 继承:即一个派生类(derived class)继承基类(base class)的字段和方法。继承也允许把一个派生类的对象作为一个基类对象对待。
- 实例化:创建一个类的实例,类的具体对象。
- 方法:类中定义的函数。
- 对象:通过类中定义的数据结构实例。对象包括两个数据成员(类变量和实例变量)和方法。
创建类
创建类,class是关键字,就好比函数中的def 一样。基本格式如
class ClassName: def 函数名(self): pass obj = ClassName() obj.函数名() #执行
创建类中,函数后面的self是必写的参数,相当于传的对象,而obj此时代表的就是一个对象。例如一个简单实例
class foo: def f(self, args): return args s = foo() ret = s.f("你很帅") print(ret)
面向对象的三大特性:封装、继承、多态
封装
就是把内容封装在某处,日后好调用。首先看一个例子
class foo: def f(self,args): print(self.name, self.age, self.gender,args) z = foo() z.name = "flash" z.age = 18 z.gender = "man" z.f("你很帅") #这种也能实现封装的功能,但是会传很多参数,显得比较low
其实在类中有种自带的特殊的方法:构造方法,这让我们实现封装会比较方便和美观了。如
class Person: def __init__(self, name, age): self.n = name self.a = age def foo(self): print(self.n, self.a) flash = Person("Flash",20) flash.foo() #注:此时的__init__是构造方法,他会根据类创建的时候自动执行。
继承
和现实中的继承类似,都是子类继承父类。继承中默认是全部继承过来,但也可以只继承优点。首先看一个全部继承的例子。
class Father: def eat(self): print("吃饭") def drink(self): print("喝水") class Son(Father): def sink(self): print("la") obj = Son() obj.sink() obj.eat() obj.drink()
有时我们不想全部继承,这是我们只需要修改一下就行
class Father: def eat(self): print("吃饭") def drink(self): print("喝水") class Son(Father): def drink(self): print("la") super(Son, self).drink()#执行父类中的drink的方法 obj = Son() obj.drink()
那么问题来了,如果一个子类有两个父类,每个父类又各有自己的父类,他们的父类又有相同父类怎么办?
在python中遵循先左后右,一条道走到黑,有相同父类时,父类最后执行的原则。
例如下面这个例子
class base: pass class F2(base): def a(self): print("f2.a") self.b() def b(self): print("f2.b") class F3(F2): def b(self): print("f3.b") class Son(F3,F2): pass obj = Son() obj.a()
多态
多态性(polymorphisn)是允许你将父对象设置成为和一个或更多的他的子对象相等的技术,赋值之后,父对象就可以根据当前赋值给它的子对象的特性以不同的方式运作。简单的说,就是一句话:允许将子类类型的指针赋值给父类类型的指针。
那么,多态的作用是什么呢?我们知道,封装可以隐藏实现细节,使得代码模块化;继承可以扩展已存在的代码模块(类);它们的目的都是为了——代码重用。而多态则是为了实现另一个目的——接口重用!多态的作用,就是为了类在继承和派生的时候,保证使用“家谱”中任一类的实例的某一属性时的正确调用。
类成员的字段和方法
应用场景
如果对象中需要保存一些值,执行某功能时,需要使用对象中的值 -> 普通方法
不需要任何对象中的值,静态方法
字段
- 普通字段:保存在对象中,执行只能通过对象访问。
- 静态字段:保存在类中, 执行 可以通过对象访问 也可以通过类访问。
方法
- 普通方法,保存在类中,由对象来调用,self=》对象
- 静态方法,保存在类中,由类直接调用
- 类方法,保存在类中,由类直接调用,cls=》当前类
属性
按方法的方式去定义,按字段的模式去调用
例如
class provice: country = "中国" #静态字段属于类 def __init__(self,n): self.name = n #普通字段属于对象 henan print(self.name) henan = provice("河南") print(provice.country) henan.name
class Foo: def f1(self): #普通方法 print(123) @staticmethod #静态方法 def sta(): print(1,2) @classmethod #类方法 def classmd(cls): print("a,b") @property #属性 def per(self): print("aaa") obj = Foo() obj.f1() Foo.sta() #调用静态方法,不用创建对象 Foo.classmd() #调用类方法 obj1 = Foo() #调用属性 obj1.per
例如用常用的property属性求分页的问题
class Paragnation: def __init__(self,page): try: p = int(page) except Exception as e: p = 1 self.page = p @property def start(self): p = (self.page -1) * 10 return p @property def end(self): p = self.page * 10 return p li = [] for i in range(1000): li.append(i) while True: p = input("请输入页码:") obj = Paragnation(p) print(li[obj.start:obj.end])
成员修饰符
- 共有成员
- 私有方法
其中私有成员的表示方法为:双下划线+字段名(__字段名)
私有成员外部不能访问,外部若访问,只能通过类里面的方法间接访问。例如
class F: def __init__(self): self.__age = 18 def Show(self): return self.__age class S(F): def __init__(self, name, gender): self.name = name self.gender = gender super(S, self).__init__() def show(self): print(self.name) # print(self.__age) #子类不能继承到父类的私有变量,否则会报错,如果要继承可以通过父类的共有方法间接访问 print(self.gender) P = S("flash","男") P.show() r = P.Show() print(r)
注:子类继承不了父类的私有方法,也就是说,在子类中不能直接访问父类的私有方法,只能通过父类的方法间接去访问。
python中常见的特殊成员
__init__ 类()自动执行 __del__ del 对象[222] __call__ 对象() 类()() 自动执行 __int__ int(对象) __str__ str() __add__ #对象的封装的加法 __dict__ # 讲对象中封装的所有内容通过字典的形式返回 __getitem__ # 切片(slice类型)或者索引 __setitem__ __delitem__ __iter__ # 如果类中有 __iter__ 方法,对象=》可迭代对象 # 对象.__iter__() 的返回值: 迭代器 # for 循环,迭代器,next # for 循环,可迭代对象,对象.__iter__(),迭代器,next # 1、执行li对象的类F类中的 __iter__方法,并获取其返回值 # 2、循环上一步中返回的对象
异常处理
常用语数据库处理
主要语法块
try: 自定义内容 except Exception as e: print("消息")
下面列出几种常见模式
try: i = int(input("输入>>>>")) except IndexError as e: print("IndexError", e) except ValueError as e: print("ValueError",e) except Exception as e: print("Exception",e) else: print(i) finally: print("success")
class Foo(Exception): def __init__(self,msg): self.message = msg def __str__(self): return self.message try: raise Foo("I'm error") except Foo as e: print(e)
反射
class Foo: def __init__(self, name, age): self.name = name self.age = age def show(self): print("%s-%s" % (self.name, self.age)) obj = Foo("flash", 18) # print(obj.name) func = getattr(obj, "name") print(func) func1 = getattr(obj, "show") print(func1()) print(hasattr(obj, "name")) setattr(obj, "gender", "man") print(obj.gender) delattr(obj, "name") obj.name
单例模式
class Foo: V = None @classmethod def func(cls): if cls.V: return cls.V else: cls.V = Foo() return cls.V obj = Foo.func() print(obj.V) print(obj) obj1 = Foo.func() print(obj1)