Python 面向对象基础
面向对象编程——Object Oriented Programming,简称OOP,是一种程序设计思想。OOP把对象作为程序的基本单元,一个对象包含了数据和操作数据的函数。
面向过程的程序设计把计算机程序视为一系列的命令集合,即一组函数的顺序执行。为了简化程序设计,面向过程把函数继续切分为子函数,即把大块函数通过切割成小块函数来降低系统的复杂度。
而面向对象的程序设计把计算机程序视为一组对象的集合,而每个对象都可以接收其他对象发过来的消息,并处理这些消息,计算机程序的执行就是一系列消息在各个对象之间传递。
面向对象的编程方式的落地需要使用 “类” 和 “对象” 来实现,所以,面向对象编程其实就是对 “类” 和 “对象” 的使用。
类就是一个模板,模板里可以包含多个函数,函数里实现一些功能
对象则是根据模板创建的实例,通过实例对象可以执行类中的函数
·class 是关键字
·创建对象后面要加括号
面向对象举例
1 class add: 2 3 def foo(self, a, b): 4 print("%s" % (a + b)) 5 return 222222 6 7 obj = add() 8 c = obj.foo(1, 2) 9 print(c) 10 11 class Bar: 12 13 def foo(self, arg): 14 print(self, self.name, self.age, self.gender, arg) 15 16 z = Bar() 17 z.name = "alex" 18 z.age = 84 19 z.gender = "zhong" 20 z.foo(666) 21 22 z1 = Bar() 23 z1.name = "eric" 24 z1.age = 73 25 z1.gender = "nv" 26 z1.foo(699999)
面向对象三大特性
1.封装
封装就是把内容封到某个地方,供调用时使用
如例子
class Person: def __init__(self, name, age): self.n = name self.a = age def show(self): print("%s -%s" % (self.n, self.a)) hu = Person("huxianglin", 25) # 创建对象 hu.show() liu = Person("dadd", 55) # 创建对象 liu.show()
self 是一个形式参数,当执行 hu = Person("huxianglin", 25)时,self 相当于 hu
self.name 这种形式叫做实例属性
当对象被创建时,先去寻找class中的__init__中的内容,存在则执行其中的内容,不存在则不执行。
继承
子类可以继承父类里面的各个方法,可以在子类中添加新的方法,或者用相同的函数名重写父类中用不到的方法。
class 子类(父类):
1 class F: 2 def f1(self, b): 3 print("F.f1", b) 4 5 def f2(self): 6 print("F.f2") 7 8 9 class S(F): 10 11 def s1(self): 12 print("S.s1") 13 14 15 def f2(self): 16 super(S, self).f2() 17 print("S.f2") 18 F.f2(self) 19 20 obj = S() 21 22 obj.s1() 23 obj.f1(2) 24 obj.f2()
python可以继承多个父类,当调用一个方法时,先在子类中寻找,找不到则按顺序从左到右在父类中寻找。__init__也是如此。
继承的顺序:python3里面都是新式类,采用了C3算法。
先采用深度优先,当出现了一个交叉点时,则不在此点中寻找,而是重走交叉的另一条路,走到此点。
如图,E继承D,C
找寻顺序为D→B1→B2→B→C→A
若在运行时,父类中出现了新的方法,则从方法定义的类里重找,无论是多少级的父类。
1 class BaseRequest: 2 pass 3 4 5 class RequestHandler(BaseRequest): 6 7 def sever_forever(self): 8 9 print("RequestHandler.sever_forever") 10 self.process_request() # 重新回到Son里寻找,最后运行Minx里的procexx_request() 11 12 def process_request(self): 13 print("RequestHandler.process_request") 14 15 16 class Minx: 17 18 def process_request(self): 19 print("minx.process_request") 20 21 22 class Son(Minx, RequestHandler): 23 pass 24 25 obj = Son() 26 obj.sever_forever() 27
多态
自带多态
进阶
类的成员
类的成员分为三大类:字段、方法和属性。
其中静态字段叫做类属性。
字段包括:普通字段和静态字段。他们在定义和使用中有所区别,其最本质的区别是内存中保存的位置不同。
·普通字段属于对象
·静态字段属于类
1 class Province: 2 3 # 静态字段,保存在类中 4 country = '中国' 5 6 def __init__(self, name): 7 8 # 普通字段,保存在对象中 9 self.name = name 10 11 12 # 直接访问普通字段 , 通过对象访问 13 obj = Province('河北省') 14 print(obj.name) 15 16 # 直接访问静态字段 ,通过类访问, 也可通过对象访问 17 Province.country 18 19 字段的定义和使用
普通字段在__init__下,静态字段不属于方法。
·静态字段在内存中值保存一份
·普通字段在每个对象中都要保存一份
应用场景:通过类创建对象时,如果每个对象都具有相同的字段,那么就使用静态字段。
方法
方法包括:普通方法、静态方法和类方法,三种方法在内存中都属于类,区别在于调用方式不同。
·普通方法:由对象调用,至少一个self参数,执行普通方法时,自动将调用该方法的对象赋值给self;
·类方法:由类调用,至少一个cls参数,执行类方法时,自动将调用该方法的类复制给cls;
·静态方法:由类调用,无默认参数
1 class Foo: 2 3 def __init__(self, name): 4 self.name = name 5 6 def ord_func(self): 7 """ 定义普通方法,至少有一个self参数 """ 8 9 # print self.name 10 print('普通方法') 11 12 @classmethod 13 def class_func(cls): 14 """ 定义类方法,至少有一个cls参数
cls是类名,保存在类中
""" 15 16 print('类方法') 17 18 @staticmethod 19 def static_func(): 20 """ 定义静态方法 ,无默认参数""" 21 22 print('静态方法') 23 24 25 # 调用普通方法 26 f = Foo() 27 f.ord_func() 28 29 # 调用类方法 30 Foo.class_func() 31 32 # 调用静态方法 33 Foo.static_func() 34 35 方法的定义和使用
对于所有的方法而言,均属于类中,在内存中也只保存一份。
属性
属性是普通方法的变种。
1.属性的基本使用
1 # ############### 定义 ############### 2 class Foo: 3 4 def func(self): 5 pass 6 7 # 定义属性 8 @property 9 def prop(self): 10 pass 11 # ############### 调用 ############### 12 foo_obj = Foo() 13 14 foo_obj.func() 15 foo_obj.prop #调用属性 16 17 属性的定义和使用
定义时,在普通方法上添加@property装饰器
定义时,属性仅有一个self参数
调用时,无需括号
方法: foo_obj.fun()
属性: foo_obj.prop
1 class Pergination: 2 def __init__(self, current_page): 3 try: 4 p1 = int(current_page) 5 except Exception as e: 6 p1 = 1 7 8 self.page = p1 9 10 @property 11 def start(self): 12 val = (self.page - 1) * 10 13 return val 14 15 @property 16 def end(self): 17 val2 = self.page * 10 18 return val2 19 20 21 li = [] 22 for i in range(1000): 23 li.append(i) 24 25 26 while True: 27 p = input("请输入要查看的页码:") 28 obj = Pergination(p) 29 print(li[obj.start: obj.end])
2.属性的两种定义方式
装饰器:在方法上应用装饰器
静态字段 : 在类定义值为property对象的静态字段
装饰器方式:在类的普通方法上应用@property装饰器
1 class Goods(object): 2 3 def __init__(self): 4 # 原价 5 self.original_price = 100 6 # 折扣 7 self.discount = 0.8 8 9 @property 10 def price(self): 11 # 实际价格 = 原价 * 折扣 12 new_price = self.original_price * self.discount 13 return new_price 14 15 @price.setter 16 def price(self, value): 17 self.original_price = value 18 19 @price.deltter 20 def price(self, value): 21 del self.original_price 22 23 obj = Goods() 24 obj.price # 获取商品价格 25 obj.price = 200 # 修改商品原价 26 del obj.price # 删除商品原价 # 与删除操作无关,只对应@price.deltter 27
静态字段方式,创建值为property的对象的静态字段
1 class Foo: 2 3 def get_bar(self): 4 return 'wupeiqi' 5 6 BAR = property(get_bar) 7 8 obj = Foo() 9 reuslt = obj.BAR # 自动调用get_bar方法,并获取方法的返回值 10 print(reuslt)
property的构造方法中有个四个参数
- 第一个参数是方法名,调用
对象.属性
时自动触发执行方法 - 第二个参数是方法名,调用
对象.属性 = XXX
时自动触发执行方法 - 第三个参数是方法名,调用
del 对象.属性
时自动触发执行方法 - 第四个参数是字符串,调用
对象.属性.__doc__
,此参数是该属性的描述信息
1 class Foo: 2 3 def get_bar(self): 4 return 'wupeiqi' 5 6 # *必须两个参数 7 def set_bar(self, value): 8 return return 'set value' + value 9 10 def del_bar(self): 11 return 'wupeiqi' 12 13 BAR = property(get_bar, set_bar, del_bar, 'description...') 14 15 obj = Foo() 16 17 obj.BAR # 自动调用第一个参数中定义的方法:get_bar 18 obj.BAR = "alex" # 自动调用第二个参数中定义的方法:set_bar方法,并将“alex”当作参数传入 19 del Foo.BAR # 自动调用第三个参数中定义的方法:del_bar方法 20 obj.BAE.__doc__ # 自动获取第四个参数中设置的值:description...
成员修饰符
前面带两个_的为私有成员,外部无法直接访问
1 class Foo: 2 3 def __init__(self, name, age): 4 self.name = name 5 # self.age = age 6 self.__age = age # 私有,外部无法直接访问 7 8 def show(self): 9 return self.__age 10 11 12 obj = Foo('alex', 19) 13 print(obj.name) 14 # obj.age 15 # print(obj.__age) 16 ret = obj.show() 17 print(ret)View Code
1 class Foo: 2 __v = '123' 3 4 def __init__(self): 5 pass 6 def show(self): 7 return Foo.__v 8 @staticmethod 9 def stat(): 10 return Foo.__v 11 # print(Foo.__v) 12 # ret = Foo().show() 13 # print(ret) 14 15 ret = Foo.stat() 16 print(ret)View Code2
1 class Foo: 2 def __f1(self): 3 return 123 4 5 def f2(self): 6 r = self.__f1() 7 return r 8 9 obj = Foo() 10 ret = obj.f2() 11 print(ret)View Code3
类的特殊成员
1.__init__
构造方法,创建对象时自动执行
2.__del__
析构方法,当对象在内存中被释放时自动执行
注:此方法一般无须定义,因为Python是一门高级语言,程序员在使用时无需关心内存的分配和释放,因为此工作都是交给Python解释器来执行,所以,析构函数的调用是由解释器在进行垃圾回收时自动触发执行的。
class Foo: def __del__(self): pass__del__
3.__call__
对象后面加括号触发执行
注:构造方法的执行是由创建对象触发的,即:对象 = 类名() ;而对于 __call__ 方法的执行是由对象后加括号触发的,即:对象() 或者 类()()
1 class Foo: 2 3 def __init__(self): 4 pass 5 6 def __call__(self, *args, **kwargs): 7 8 print '__call__' 9 10 11 obj = Foo() # 执行 __init__ 12 obj() # 执行 __call____call__
1 class Entity: 2 3 def __init__(self, size, x, y): 4 self.size = size 5 self.x = x 6 self.y = y 7 print(self.x, self.y) 8 9 def __call__(self, x, y): 10 self.x, self.y = x, y 11 obj = Entity(6, 8, 9) 12 13 obj(10, 19) 14 print(obj.x, obj.y) 15 # 10 19 16 # x和y的值改变了应用
4.__int__、__str__
如果一个类中定义了__str__方法,那么在打印 对象 时,默认输出该方法的返回值。
1 class Foo: 2 3 def __init__(self,n,a): 4 self.name =n 5 self.age =a 6 7 def __str__(self): 8 return '%s-%s' %(self.name,self.age,) 9 10 obj = Foo('alex', 18) 11 print(obj) #print(str(obj)) str(obj) obj中__str__,并获取其返回值__str__
int,对象,自动执行对象的 __int__方法,并将返回值赋值给int对象
1 class Foo: 2 3 def __init__(self): 4 pass 5 6 def __int__(self): 7 return 1111 8 9 def __str__(self): 10 return 'alex' 11 12 obj = Foo() 13 print(obj, type(obj)) 14 15 # int,对象,自动执行对象的 __int__方法,并将返回值赋值给int对象 16 r = int(obj) 17 print(r) 18 i = str(obj) 19 print(i) 20 """ 21 输出为 22 alex <class '__main__.Foo'> 23 1111 24 alex 25 """__int__
5.__add__
两个对象相加时,自动执行第一个对象的的 __add__方法,并且将第二个对象当作参数传递进入
1 class Foo: 2 3 def __init__(self, name, age): 4 self.name = name 5 self.age = age 6 7 def __add__(self, other): 8 # self = obj1 (alex,19) 9 # other = obj2(eric,66) 10 # return self.age + other.age 11 #return Foo('tt',99) 12 return Foo(self.name, other.age) 13 14 # def __del__(self): 15 # print('析构方法') # 对象被销毁()时,自动执行 16 17 obj1 = Foo('alex', 19) 18 obj2 = Foo('eirc', 66) 19 20 r = obj1 + obj2 21 # 两个对象相加时,自动执行第一个对象的的 __add__方法,并且将第二个对象当作参数传递进入 22 print(r, type(r)) 23 print(r.name, r.age) 24 ''' 25 输出为 26 <__main__.Foo object at 0x000001F81BD29390> <class '__main__.Foo'> 27 alex 66 28 '''__add__
6.__dict__
类的普通字段属于对象;类中的静态字段和方法等属于类
将对象中所封装的元素通过字典的形式返回
1 class Province: 2 3 country = 'China' 4 5 def __init__(self, name, count): 6 self.name = name 7 self.count = count 8 9 def func(self, *args, **kwargs): 10 print('func') 11 12 # 获取类的成员,即:静态字段、方法、 13 print(Province.__dict__) 14 # 输出:{'country': 'China', '__module__': '__main__', 'func': <function func at 0x10be30f50>, '__init__': <function __init__ at 0x10be30ed8>, '__doc__': None} 15 16 obj1 = Province('HeBei',10000) 17 print(obj1.__dict__) 18 # 获取 对象obj1 的成员 19 # 输出:{'count': 10000, 'name': 'HeBei'} 20 21 obj2 = Province('HeNan', 3888) 22 print(obj2.__dict__) 23 # 获取 对象obj1 的成员 24 # 输出:{'count': 3888, 'name': 'HeNan'}__dict__
7.__getitem__、__setitem__、__delitem__
用于索引操作,如字典、列表
1 class Foo(object): 2 def __getitem__(self, key): 3 print('__getitem__', key) 4 5 6 def __setitem__(self, key, value): 7 print('__setitem__', key, value) 8 9 10 def __delitem__(self, key): 11 print('__delitem__', key) 12 13 14 obj = Foo() 15 16 result = obj[0] # 自动触发执行 __getitem__ 17 obj[1] = 'wupeiqi' # 自动触发执行 __setitem__ 18 del obj[2] # 自动触发执行 __delitem__View Code
1 class Foo: 2 3 def __init__(self, name,age): 4 self.name = name 5 self.age = age 6 7 def __getitem__(self, item): 8 # return item+10 9 # 如果item是基本类型:int,str,索引获取 10 # slice对象的话,切片 11 if type(item) == slice: 12 print('调用这希望内部做切片处理') 13 else: 14 print(item.start) 15 print(item.stop) 16 print(item.step) 17 print('调用这希望内部做索引处理') 18 19 def __setitem__(self, key, value): 20 print(key, value) 21 22 def __delitem__(self, key): 23 print(key) 24 25 li = Foo('alex', 18) 26 # li[123] 27 li[1:4:2] 28 29 li[1:3] = [11, 22] 30 31 del li[1: 3] 32 ''' 33 输出为 34 调用这希望内部做切片处理 35 slice(1, 3, None) [11, 22] 36 slice(1, 3, None) 37 '''View Code2
8.__iter__
如果类中有 __iter__ 方法,对象=》可迭代对象
对象.__iter__() 的返回值: 迭代器
for 循环,迭代器,next
for 循环,可迭代对象,对象.__iter__(),迭代器,next
1、执行li对象的类F类中的 __iter__方法,并获取其返回值
2、循环上一步中返回的对象
元类
a. Python中一切事物都是对象
b.
class Foo:
pass
obj = Foo()
# obj是对象,Foo类
# Foo类也是一个对象,type的对象
c.
类都是type类的对象 type(..)
“对象”都是以类的对象 类()
创建类的另一种方法:通过type的构造函数
1 def func(self): 2 print('hello wupeiqi') 3 4 5 6 Foo = type('Foo', (object,), {'func': func}) 7 # type第一个参数:类名 8 # type第二个参数:当前类的基类 9 # type第三个参数:类的成员 10 a = Foo() 11 a.func()
类中有一个属性 __metaclass__,其用来表示该类由 谁 来实例化创建,所以,我们可以为 __metaclass__ 设置一个type类的派生类,从而查看 类 创建的过程。
class MyType(type): def __init__(self, what, bases=None, dict=None): super(MyType, self).__init__(what, bases, dict) def __call__(self, *args, **kwargs): obj = self.__new__(self, *args, **kwargs) self.__init__(obj) class Foo: __metaclass__ = MyType def __init__(self, name): self.name = name def __new__(cls, *args, **kwargs): return "对象" # 第一阶段:解释器从上到下执行代码创建Foo类 # 第二阶段:通过Foo类创建obj对象 obj = Foo("xiaoming") # Foo由MyType创建,所以,Foo()先执行MyType()中的__call__
通过字符串操作对象中的成员getattr(),hasattr(),setattr(),delattr()
hasattr(object, name)
判断一个对象里面是否有name属性或者name方法,返回BOOL值,有name特性返回True, 否则返回False。
name要加引号
1 >>> class test(): 2 ... name="xiaohua" 3 ... def run(self): 4 ... return "HelloWord" 5 ... 6 >>> t=test() 7 >>> hasattr(t, "name") #判断对象有name属性 8 True 9 >>> hasattr(t, "run") #判断对象有run方法 10 True 11 >>>
getattr(object, name[, default])
获取对象object的属性或者方法,如果存在打印出来,如果不存在,打印出默认值,默认值可选。
需要注意的是,如果是返回的对象的方法,返回的是方法的内存地址,如果需要运行这个方法,
可以在后面添加一对括号。
1 >>> class test(): 2 ... name="xiaohua" 3 ... def run(self): 4 ... return "HelloWord" 5 ... 6 >>> t=test() 7 >>> getattr(t, "name") #获取name属性,存在就打印出来。 8 'xiaohua' 9 >>> getattr(t, "run") #获取run方法,存在就打印出方法的内存地址。 10 <bound method test.run of <__main__.test instance at 0x0269C878>> 11 >>> getattr(t, "run")() #获取run方法,后面加括号可以将这个方法运行。 12 'HelloWord' 13 >>> getattr(t, "age") #获取一个不存在的属性。 14 Traceback (most recent call last): 15 File "<stdin>", line 1, in <module> 16 AttributeError: test instance has no attribute 'age' 17 >>> getattr(t, "age","18") #若属性不存在,返回一个默认值。 18 '18' 19 >>>
setattr(object, name, values)
给对象的属性赋值,若属性不存在,先创建再赋值。
1 >>> class test(): 2 ... name="xiaohua" 3 ... def run(self): 4 ... return "HelloWord" 5 ... 6 >>> t=test() 7 >>> hasattr(t, "age") #判断属性是否存在 8 False 9 >>> setattr(t, "age", "18") #为属相赋值,并没有返回值 10 >>> hasattr(t, "age") #属性存在了 11 True 12 >>>
delattr(object, name)
删除对象的属性
综合应用
1 >>> class test(): 2 ... name="xiaohua" 3 ... def run(self): 4 ... return "HelloWord" 5 ... 6 >>> t=test() 7 >>> getattr(t, "age") #age属性不存在 8 Traceback (most recent call last): 9 File "<stdin>", line 1, in <module> 10 AttributeError: test instance has no attribute 'age' 11 >>> getattr(t, "age", setattr(t, "age", "18")) #age属性不存在时,设置该属性 12 '18' 13 >>> getattr(t, "age") #可检测设置成功 14 '18' 15 >>>
转载于:https://www.cnblogs.com/bw13/p/5893691.html
- 点赞
- 收藏
- 分享
- 文章举报
- python基础11_OOP_面向 对象
- 笔记:python基础之面向对象特性——封装
- 从零开始学Python第六周:面向对象基础(需修改)
- python基础--面向对象
- Python面向对象基础
- Python基础:面向对象基础(二) 继承
- Python面向对象基础引入
- 12-python基础知识-面向对象
- Python基础---面向对象
- Python面向对象基础入门之编码细节与注意事项
- Python基础 面向对象常用魔术方法
- Python面向对象基础
- python_fullstack基础(十六)-面向对象进阶
- Python --- Python面向对象学习 Day01 (面向对象基础)
- python面向对象基础相关知识点
- python之路 面向对象基础 XML
- 我与python约个会:27. 企业级开发基础8:面向对象扩展
- 第四节 Python基础-面向对象
- python基础之面向对象高级编程
- Python基础知识-----面向对象