Python 面向对象基础
面向对象编程——Object Oriented Programming,简称OOP,是一种程序设计思想。OOP把对象作为程序的基本单元,一个对象包含了数据和操作数据的函数。
面向过程的程序设计把计算机程序视为一系列的命令集合,即一组函数的顺序执行。为了简化程序设计,面向过程把函数继续切分为子函数,即把大块函数通过切割成小块函数来降低系统的复杂度。
而面向对象的程序设计把计算机程序视为一组对象的集合,而每个对象都可以接收其他对象发过来的消息,并处理这些消息,计算机程序的执行就是一系列消息在各个对象之间传递。
面向对象的编程方式的落地需要使用 “类” 和 “对象” 来实现,所以,面向对象编程其实就是对 “类” 和 “对象” 的使用。
类就是一个模板,模板里可以包含多个函数,函数里实现一些功能
对象则是根据模板创建的实例,通过实例对象可以执行类中的函数

·class 是关键字
·创建对象后面要加括号
面向对象举例
 class add:
     def foo(self, a, b):
         print("%s" % (a + b))
         return 222222
 obj = add()
 c = obj.foo(1, 2)
 print(c)
 class Bar:
     def foo(self, arg):
         print(self, self.name, self.age, self.gender, arg)
 z = Bar()
 z.name = "alex"
 z.age = 84
 z.gender = "zhong"
 z.foo(666)
 z1 = Bar()
 z1.name = "eric"
 z1.age = 73
 z1.gender = "nv"
 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 子类(父类):
class F:
def f1(self, b):
print("F.f1", b) def f2(self):
print("F.f2") class S(F): def s1(self):
print("S.s1") def f2(self):
super(S, self).f2()
print("S.f2")
F.f2(self) obj = S() obj.s1()
obj.f1(2)
obj.f2()
python可以继承多个父类,当调用一个方法时,先在子类中寻找,找不到则按顺序从左到右在父类中寻找。__init__也是如此。
继承的顺序:python3里面都是新式类,采用了C3算法。
先采用深度优先,当出现了一个交叉点时,则不在此点中寻找,而是重走交叉的另一条路,走到此点。

如图,E继承D,C
找寻顺序为D→B1→B2→B→C→A
若在运行时,父类中出现了新的方法,则从方法定义的类里重找,无论是多少级的父类。
class BaseRequest:
pass class RequestHandler(BaseRequest): def sever_forever(self): print("RequestHandler.sever_forever")
self.process_request() # 重新回到Son里寻找,最后运行Minx里的procexx_request() def process_request(self):
print("RequestHandler.process_request") class Minx: def process_request(self):
print("minx.process_request") class Son(Minx, RequestHandler):
pass obj = Son()
obj.sever_forever()
多态
自带多态
进阶
类的成员
类的成员分为三大类:字段、方法和属性。
其中静态字段叫做类属性。
字段包括:普通字段和静态字段。他们在定义和使用中有所区别,其最本质的区别是内存中保存的位置不同。
·普通字段属于对象
·静态字段属于类
 class Province:
     # 静态字段,保存在类中
     country = '中国'
     def __init__(self, name):
         # 普通字段,保存在对象中
         self.name = name
 # 直接访问普通字段  , 通过对象访问
 obj = Province('河北省')
 print(obj.name)
 # 直接访问静态字段 ,通过类访问, 也可通过对象访问
 Province.country
 字段的定义和使用
普通字段在__init__下,静态字段不属于方法。
·静态字段在内存中值保存一份
·普通字段在每个对象中都要保存一份
应用场景:通过类创建对象时,如果每个对象都具有相同的字段,那么就使用静态字段。
方法
方法包括:普通方法、静态方法和类方法,三种方法在内存中都属于类,区别在于调用方式不同。
·普通方法:由对象调用,至少一个self参数,执行普通方法时,自动将调用该方法的对象赋值给self;
·类方法:由类调用,至少一个cls参数,执行类方法时,自动将调用该方法的类复制给cls;
·静态方法:由类调用,无默认参数
 class Foo:
     def __init__(self, name):
         self.name = name
     def ord_func(self):
         """ 定义普通方法,至少有一个self参数 """
         # print self.name
         print('普通方法')
     @classmethod
     def class_func(cls):
         """ 定义类方法,至少有一个cls参数 
           cls是类名,保存在类中
       """
         print('类方法')
     @staticmethod
     def static_func():
         """ 定义静态方法 ,无默认参数"""
         print('静态方法')
 # 调用普通方法
 f = Foo()
 f.ord_func()
 # 调用类方法
 Foo.class_func()
 # 调用静态方法
 Foo.static_func()
 方法的定义和使用
对于所有的方法而言,均属于类中,在内存中也只保存一份。
属性
属性是普通方法的变种。
1.属性的基本使用
# ############### 定义 ###############
class Foo: def func(self):
pass # 定义属性
@property
def prop(self):
pass
# ############### 调用 ###############
foo_obj = Foo() foo_obj.func()
foo_obj.prop #调用属性 属性的定义和使用
定义时,在普通方法上添加@property装饰器
定义时,属性仅有一个self参数
调用时,无需括号
方法: foo_obj.fun()
属性: foo_obj.prop
class Pergination:
def __init__(self, current_page):
try:
p1 = int(current_page)
except Exception as e:
p1 = 1 self.page = p1 @property
def start(self):
val = (self.page - 1) * 10
return val @property
def end(self):
val2 = self.page * 10
return val2 li = []
for i in range(1000):
li.append(i) while True:
p = input("请输入要查看的页码:")
obj = Pergination(p)
print(li[obj.start: obj.end])
2.属性的两种定义方式
装饰器:在方法上应用装饰器
静态字段 : 在类定义值为property对象的静态字段
装饰器方式:在类的普通方法上应用@property装饰器
 class Goods(object):
     def __init__(self):
         # 原价
         self.original_price = 100
         # 折扣
         self.discount = 0.8
     @property
     def price(self):
         # 实际价格 = 原价 * 折扣
         new_price = self.original_price * self.discount
         return new_price
     @price.setter
     def price(self, value):
         self.original_price = value
     @price.deltter
     def price(self, value):
         del self.original_price
 obj = Goods()
 obj.price         # 获取商品价格
 obj.price = 200   # 修改商品原价
 del obj.price     # 删除商品原价   # 与删除操作无关,只对应@price.deltter
 
静态字段方式,创建值为property的对象的静态字段
 class Foo:
     def get_bar(self):
         return 'wupeiqi'
     BAR = property(get_bar)
 obj = Foo()
 reuslt = obj.BAR        # 自动调用get_bar方法,并获取方法的返回值
 print(reuslt)
property的构造方法中有个四个参数
- 第一个参数是方法名,调用 
对象.属性时自动触发执行方法 - 第二个参数是方法名,调用
对象.属性 = XXX时自动触发执行方法 - 第三个参数是方法名,调用
del 对象.属性时自动触发执行方法 - 第四个参数是字符串,调用
对象.属性.__doc__,此参数是该属性的描述信息 
 class Foo:
     def get_bar(self):
         return 'wupeiqi'
     # *必须两个参数
     def set_bar(self, value):
         return return 'set value' + value
     def del_bar(self):
         return 'wupeiqi'
     BAR = property(get_bar, set_bar, del_bar, 'description...')
 obj = Foo()
 obj.BAR              # 自动调用第一个参数中定义的方法:get_bar
 obj.BAR = "alex"     # 自动调用第二个参数中定义的方法:set_bar方法,并将“alex”当作参数传入
 del Foo.BAR          # 自动调用第三个参数中定义的方法:del_bar方法
 obj.BAE.__doc__      # 自动获取第四个参数中设置的值:description...
成员修饰符
前面带两个_的为私有成员,外部无法直接访问
 class Foo:
     def __init__(self, name, age):
         self.name = name
         # self.age = age
         self.__age = age   # 私有,外部无法直接访问
     def show(self):
         return self.__age
 obj = Foo('alex', 19)
 print(obj.name)
 # obj.age
 # print(obj.__age)
 ret = obj.show()
 print(ret)
class Foo:
__v = '' def __init__(self):
pass
def show(self):
return Foo.__v
@staticmethod
def stat():
return Foo.__v
# print(Foo.__v)
# ret = Foo().show()
# print(ret) ret = Foo.stat()
print(ret)
2
class Foo:
def __f1(self):
return 123 def f2(self):
r = self.__f1()
return r obj = Foo()
ret = obj.f2()
print(ret)
3
类的特殊成员
1.__init__
构造方法,创建对象时自动执行
2.__del__
析构方法,当对象在内存中被释放时自动执行
注:此方法一般无须定义,因为Python是一门高级语言,程序员在使用时无需关心内存的分配和释放,因为此工作都是交给Python解释器来执行,所以,析构函数的调用是由解释器在进行垃圾回收时自动触发执行的。
class Foo:
    def __del__(self):
        pass
__del__
3.__call__
对象后面加括号触发执行
注:构造方法的执行是由创建对象触发的,即:对象 = 类名() ;而对于 __call__ 方法的执行是由对象后加括号触发的,即:对象() 或者 类()()
 class Foo:
     def __init__(self):
         pass
     def __call__(self, *args, **kwargs):
         print '__call__'
 obj = Foo() # 执行 __init__
 obj()       # 执行 __call__
__call__
 class Entity:
     def __init__(self, size, x, y):
         self.size = size
         self.x = x
         self.y = y
         print(self.x, self.y)
     def __call__(self, x, y):
         self.x, self.y = x, y
 obj = Entity(6, 8, 9)
 obj(10, 19)
 print(obj.x, obj.y)
 # 10 19
 # x和y的值改变了
应用
4.__int__、__str__
如果一个类中定义了__str__方法,那么在打印 对象 时,默认输出该方法的返回值。
 class Foo:
     def __init__(self,n,a):
         self.name =n
         self.age =a
     def __str__(self):
         return '%s-%s' %(self.name,self.age,)
 obj = Foo('alex', 18)
 print(obj) #print(str(obj)) str(obj)   obj中__str__,并获取其返回值
__str__
int,对象,自动执行对象的 __int__方法,并将返回值赋值给int对象
 class Foo:
     def __init__(self):
         pass
     def __int__(self):
         return 1111
     def __str__(self):
         return 'alex'
 obj = Foo()
 print(obj, type(obj))
 # int,对象,自动执行对象的 __int__方法,并将返回值赋值给int对象
 r = int(obj)
 print(r)
 i = str(obj)
 print(i)
 """
 输出为
 alex <class '__main__.Foo'>
 1111
 alex
 """
__int__
5.__add__
两个对象相加时,自动执行第一个对象的的 __add__方法,并且将第二个对象当作参数传递进入
 class Foo:
     def __init__(self, name, age):
         self.name = name
         self.age = age
     def __add__(self, other):
         # self = obj1 (alex,19)
         # other = obj2(eric,66)
         # return self.age + other.age
         #return Foo('tt',99)
         return Foo(self.name, other.age)
     # def __del__(self):
     #     print('析构方法')  # 对象被销毁()时,自动执行
 obj1 = Foo('alex', 19)
 obj2 = Foo('eirc', 66)
 r = obj1 + obj2
 # 两个对象相加时,自动执行第一个对象的的 __add__方法,并且将第二个对象当作参数传递进入
 print(r, type(r))
 print(r.name, r.age)
 '''
 输出为
 <__main__.Foo object at 0x000001F81BD29390> <class '__main__.Foo'>
 alex 66
 '''
__add__
6.__dict__
类的普通字段属于对象;类中的静态字段和方法等属于类
将对象中所封装的元素通过字典的形式返回
 class Province:
     country = 'China'
     def __init__(self, name, count):
         self.name = name
         self.count = count
     def func(self, *args, **kwargs):
         print('func')
 # 获取类的成员,即:静态字段、方法、
 print(Province.__dict__)
 # 输出:{'country': 'China', '__module__': '__main__', 'func': <function func at 0x10be30f50>, '__init__': <function __init__ at 0x10be30ed8>, '__doc__': None}
 obj1 = Province('HeBei',10000)
 print(obj1.__dict__)
 # 获取 对象obj1 的成员
 # 输出:{'count': 10000, 'name': 'HeBei'}
 obj2 = Province('HeNan', 3888)
 print(obj2.__dict__)
 # 获取 对象obj1 的成员
 # 输出:{'count': 3888, 'name': 'HeNan'}
__dict__
7.__getitem__、__setitem__、__delitem__
用于索引操作,如字典、列表
class Foo(object):
def __getitem__(self, key):
print('__getitem__', key) def __setitem__(self, key, value):
print('__setitem__', key, value) def __delitem__(self, key):
print('__delitem__', key) obj = Foo() result = obj[0] # 自动触发执行 __getitem__
obj[1] = 'wupeiqi' # 自动触发执行 __setitem__
del obj[2] # 自动触发执行 __delitem__
 class Foo:
     def __init__(self, name,age):
         self.name = name
         self.age = age
     def __getitem__(self, item):
         # return item+10
         # 如果item是基本类型:int,str,索引获取
         # slice对象的话,切片
         if type(item) == slice:
             print('调用这希望内部做切片处理')
         else:
             print(item.start)
             print(item.stop)
             print(item.step)
             print('调用这希望内部做索引处理')
     def __setitem__(self, key, value):
         print(key, value)
     def __delitem__(self, key):
         print(key)
 li = Foo('alex', 18)
 # li[123]
 li[1:4:2]
 li[1:3] = [11, 22]
 del li[1: 3]
 '''
 输出为
 调用这希望内部做切片处理
 slice(1, 3, None) [11, 22]
 slice(1, 3, None)
 '''
2
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的构造函数
def func(self):
print('hello wupeiqi') Foo = type('Foo', (object,), {'func': func})
# type第一个参数:类名
# type第二个参数:当前类的基类
# type第三个参数:类的成员
a = Foo()
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要加引号
>>> class test():
... name="xiaohua"
... def run(self):
... return "HelloWord"
...
>>> t=test()
>>> hasattr(t, "name") #判断对象有name属性
True
>>> hasattr(t, "run") #判断对象有run方法
True
>>>
getattr(object, name[, default])
获取对象object的属性或者方法,如果存在打印出来,如果不存在,打印出默认值,默认值可选。
需要注意的是,如果是返回的对象的方法,返回的是方法的内存地址,如果需要运行这个方法,
可以在后面添加一对括号。
>>> class test():
... name="xiaohua"
... def run(self):
... return "HelloWord"
...
>>> t=test()
>>> getattr(t, "name") #获取name属性,存在就打印出来。
'xiaohua'
>>> getattr(t, "run") #获取run方法,存在就打印出方法的内存地址。
<bound method test.run of <__main__.test instance at 0x0269C878>>
>>> getattr(t, "run")() #获取run方法,后面加括号可以将这个方法运行。
'HelloWord'
>>> getattr(t, "age") #获取一个不存在的属性。
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: test instance has no attribute 'age'
>>> getattr(t, "age","") #若属性不存在,返回一个默认值。
''
>>>
setattr(object, name, values)
给对象的属性赋值,若属性不存在,先创建再赋值。
>>> class test():
... name="xiaohua"
... def run(self):
... return "HelloWord"
...
>>> t=test()
>>> hasattr(t, "age") #判断属性是否存在
False
>>> setattr(t, "age", "") #为属相赋值,并没有返回值
>>> hasattr(t, "age") #属性存在了
True
>>>
delattr(object, name)
删除对象的属性
综合应用
>>> class test():
... name="xiaohua"
... def run(self):
... return "HelloWord"
...
>>> t=test()
>>> getattr(t, "age") #age属性不存在
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: test instance has no attribute 'age'
>>> getattr(t, "age", setattr(t, "age", "")) #age属性不存在时,设置该属性
''
>>> getattr(t, "age") #可检测设置成功
''
>>>
Python 面向对象基础的更多相关文章
- Python 面向对象 基础
		
编程范式概述:面向过程 和 面向对象 以及函数式编程 面向过程:(Procedure Oriented)是一种以事件为中心的编程思想. 就是分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现 ...
 - python面向对象基础
		
面向对象基础 1. 简述 编程方式: 面向过程: 根据代码在脚本的堆叠顺序,从上到下依次执行 函数式编程:将相同功能的代码封装到函数中,直接调用即可,减少代码重复性 面向对象:对函数进行分类和封装,将 ...
 - Python 面向对象基础知识
		
面向对象基础知识 1.什么是面向对象编程? - 以前使用函数 - 类 + 对象 2.什么是类什么是对象,又有什么关系? class 类: def 函数1(): pass def 函数2(): pass ...
 - python 面向对象基础和高级复习
		
面向对象基础 面向对象编程 面向过程编程:类似于工厂的流水线 优点:逻辑清晰 缺点:扩展性差 面向对象编程:核心是对象二字,对象属性和方法的集合体,面向对象编程就是一堆对象交互 优点:扩展性强 缺点: ...
 - 十六、python面向对象基础篇
		
面向对象基础: 在了解面向对象之前,先了解下变成范式: 编程范式是一类典型的编程风格,是一种方法学 编程范式决定了程序员对程序执行的看法 oop中,程序是一系列对象的相互作用 python支持多种编程 ...
 - 1.Python面向对象基础
		
面向对象(OOP) 面向对象编程--object oriented programming 简写 OOP 面向过程和面向对象的区别: 面向过程: 1.把完成某一个需求的所有步骤从头到尾逐步实现 2 ...
 - [python面向对象]--基础篇
		
1.#类 #类就是一个模板,模板里可以包含多个函数,函数里实现一些功能 #定义一个类 class bar: def foo(self,agr): print(self,agr) obj = bar() ...
 - Python面向对象基础:编码细节和注意事项
		
在前面,我用了3篇文章解释python的面向对象: 面向对象:从代码复用开始 面向对象:设置对象属性 类和对象的名称空间 本篇是第4篇,用一个完整的示例来解释面向对象的一些细节. 例子的模型是父类Em ...
 - Python面向对象基础一
		
公司可能过一两个月就要从深圳搬到东莞松山湖,项目组的现在有的在转Java或其他语言的,问我们要不要转java+hoodap+spark方向,我还是先不转,毕竟之前是从ios转回C#,这现在在转其他的那 ...
 - python面向对象基础-01
		
面向对象(OOP)基本概念 前言 话说三国时期曹军于官渡大败袁绍,酒席之间,曹操诗兴大发,吟道:喝酒唱歌,人生真爽! 众将直呼:"丞相好诗",于是命印刷工匠刻板印刷以流传天下; 待 ...
 
随机推荐
- vi常用命令集锦
			
转载,原文地址:http://blog.csdn.net/hackbuteer1/article/details/6575232 vi编辑器有3种模式:命令模式.输入模式.末行模式.掌握这三种模式十分 ...
 - poj 3579 Median (二分搜索之查找第k大的值)
			
Description Given N numbers, X1, X2, ... , XN, let us calculate the difference of every pair of numb ...
 - 由查找session IP 展开---函数、触发器、包
			
由查找session IP 展开---函数.触发器.包 一.userenv函数.sys_context函数 --查看当前client会话的session IP信息 SQL>select sys_ ...
 - linux逻辑卷管理
			
近期在进行linux充电,依据网络资料自己整理的资料,分享一下 ---------------------------------------------------------- Linux逻辑卷管 ...
 - 《JavaScript 闯关记》之事件
			
JavaScript 程序采用了异步事件驱动编程模型.在这种程序设计风格下,当文档.浏览器.元素或与之相关的对象发生某些有趣的事情时,Web 浏览器就会产生事件(event).例如,当 Web 浏览器 ...
 - Visual Studio - 提升幸福感的N个快捷键
			
现代化IDE给程序猿提供了极大的方便,掌握一些优秀的开发工具,使我们写代码时有行云流水般的快感. VS作为宇宙最强没有之一的IDE,用起来也是好幸福.下面是我最常用的快捷键,已经印在手指上,每次好像不 ...
 - js中的eval方法转换对象时,为何一定要加上括号?
			
待转换的是一个Json字符串: {'name':'新欢'} 而使用如下这种方式调用则会抛出语法异常, eval("{'name':'新欢'}"); 必须加上括号才行 eval(&q ...
 - xutils的HttpUtils,Post和Get基本使用,以及BitmapUtils的简单使用
			
开篇报错注意:本教程是基于xUtils-2.6.14.jar版本实现的 由于studio中6.0以后安卓取消了httpclient,而xutils则基于httpclient开发的,所以现在无法使用,将 ...
 - [Leetcode] Search In Rotated Sorted Array (C++)
			
题目: Suppose a sorted array is rotated at some pivot unknown to you beforehand. (i.e., 0 1 2 4 5 6 7 ...
 - block中无法使用C数组变量
			
在Objective-C的block中无法使用C数组,即使我们不对C数组做任何改变,编译的时候也会报错: #include <stdio.h> int main() { const cha ...