全方面了解python面向对象

        面向对象主要包含,类和对象。类就是一类对象抽象出来的,是具有相同属性和行为事物的统称。我们的类主要分为:类名、属性、方法,下面主要以这三点进行概述。在类的高级使用主要是以面向对象的三大特性来介绍:封装、继承、多态。主要是以继承来介绍。

基本格式

class 类名:

    方法列表

在python2 分为新式类和经典类。但是在python3中默认都是新式类,继承的是object

demo 

class Demo():

    name = "yuge"  #类属性

    def __init__(self):

        self.user_name = "rookie"  # 实例属性

    def func(self):  # 类方法     后面会有介绍

        pass

对象创建

d  = Demo()

一个类可以创建多个对象。

比如说桌子是一个类,属性就是颜色、大小。它的方法就是它的作用。

那么可以跟着这个对象创建出不同的桌子,学生桌、饭桌等。那么创建出来的集体的桌子就是对象了。

一、类名

类名定义遵循PEP8规范,大驼峰命名法。

二、属性

    1、类属性

         在上面的demo中 name 就是类属性,在创建出来的所有对象中都可以使用。

        添加

        添加有三种方式,

        1)直接在类里面添加,在类方法上面

        2)直接使用 类对象名.属性名   Demo.name ="rooke"

        3)使用类方法用 cls.属性名 

        调用:

        类名.属性名   

        对象.属性名  注意:如果有实例属性和类属性同名,在调用时会使用类属性

    2、实例属性

    我们再开发中用的最多的就是实例属性,所谓实例属性就是创建实例对象所独立拥有的,每个对象所创建的实例属性互不相干。

    3、私有属性

    私有属性即为在外部不能访问的属性,只有在本类中使用的属性。实例属性和类属性都可以设置为私有属性。

    私有属性就是在属性前面加上两个下划线  __name 

demo

class  Demo()

    def __init__(self):

        self.__name = "rookie"  #定义私有属性

d = Demo()

print(d.__name)   #当我们去打印的时候无法获取到私有属性。

    添加

    1)在方法中

      自己方法中添加

        自己定义的方法中可以使用 self.属性名 = 变量 赋值添加

       __init__(self)  中添加

       __init__ 方法是魔法方法,每次创建对象后进行初始化操作,在这里我们进行初始化属性。

        self.属性名 = 变量 赋值添加

       在使用__init__方法时,可以接收参数来进行初始化

    demo:

    class Demo():

        name = "yuge"  #类属性

        def __init__(self,name):  #接收传来的参数

            self.user_name = name  # 实例属性进行保存使用

    d = Demo("rookie")   #在创建时需要传递参数

    在__init__,也可以传入不定长参数,默认参数,和方法的使用一样,只不过第一个参数必须是self

    self:指的是本类,我们也可以理解为:谁调用的我(创建的实例对象是谁)那么self指的就是谁

    所谓的self,可以理解为自己

    可以把self当做C++中类里面的this指针一样理解,就是对象自身的意思

    某个对象调用其方法时,python解释器会把这个对象作为第一个参数传递给self,所以开发者只需要传递后面的   参数即可。

    self仅仅是一个变量名,也可将self换为其他任意的名字,但是为了能够让其他开发人员能明白这变量的意思,因此一般都会self当做名字。

    2)对象名.属性赋值

    调用

    对象名.属性名

    在self中保存的实例属性,那么在本类中所有方法都可以进行使用  self.属性名  

三、方法

    1、实例方法

    实例方法就是一个类里面创建的方法,它的使用和函数的使用几乎相同。只不过在穿件实例方法的时候第一个参数时self(一般我们都是用的self,指的是自己)。传参和返回值和函数使用一样。

    在调用的时候使用 对象名.方法名

demo

class Demo():

    def  func(self): #定义方法

        print("rookie 写代码")

d = Demo()  #创建对象

d.func()        #调用实例方法

     2、类方法

    类方法是在实例方法上面加上@classmethod装饰器,传入的self修改为cls参数。一般情况下类方法是用来修改类属性的。类属性一般定义为私有属性。在使用的时候可以  类名.方法名 也可以 类对象.方法名  来调用

    3、静态方法

    静态方法的使用比较少,就是在实例方法的上面加上@staticmethod装饰器,方法里面不用传递self、cls参数。使用的时候和类方法类似。当方法不需要用到类中的属性时候可以使用,因为它没有self、cls参数。

    4、魔法方法

    上边提到的初始化__itit__()方法的时候就是一个魔法方法,魔法方法是类中定义的方法,由类自己调用,不需要我们自己手动调用的方法,一般情况格式为__名字__()

__init__(self[, ...])    

构造器,当一个实例被创建的时候调用的初始化方法

__new__(cls[, ...])

1. __new__ 是在一个对象实例化的时候所调用的第一个方法

2. 它的第一个参数是这个类,其他的参数是用来直接传递给 __init__ 方法

3. __new__ 决定是否要使用该 __init__ 方法,因为 __new__ 可以调用其他类的构造方法或者直接返回别的实例对象来作为本类的实例,如果 __new__ 没有返回实例对象,则 __init__ 不会被调用

4. __new__ 主要是用于继承一个不可变的类型比如一个 tuple 或者 string

__del__(self)

析构器,当一个实例被销毁的时候调用的方法

__call__(self[, args...])

允许一个类的实例像函数一样被调用:x(a, b) 调用 x.__call__(a, b)  当我们创建一个对象后可以直接进行 对象() 会直接调用__call__方法

__len__(self)

定义当被 len() 调用时的行为

__repr__(self)

定义当被 repr() 调用时的行为,和__str__ 类似

__str__(self)

定义当被 str() 调用时的行为。我们可以直接打印对象名,会调用__str__方法

__bool__(self)

定义当被 bool() 调用时的行为,应该返回 True 或 False

以上是基础的魔法方法 还有更多的魔法方法

__bytes__(self)定义当被 bytes() 调用时的行为

__hash__(self)定义当被 hash() 调用时的行为

__format__(self, format_spec)定义当被 format() 调用时的行为

__getattr__(self, name)定义当用户试图获取一个不存在的属性时的行为

__getattribute__(self, name)定义当该类的属性被访问时的行为

__setattr__(self, name, value)定义当一个属性被设置时的行为

__delattr__(self, name)定义当一个属性被删除时的行为

__dir__(self)定义当 dir() 被调用时的行为

__get__(self, instance, owner)定义当描述符的值被取得时的行为

__set__(self, instance, value)定义当描述符的值被改变时的行为

__delete__(self, instance)定义当描述符的值被删除时的行为

 比较操作符

__lt__(self, other)定义小于号的行为:x < y 调用 x.__lt__(y)

__le__(self, other)定义小于等于号的行为:x <= y 调用 x.__le__(y)

__eq__(self, other)定义等于号的行为:x == y 调用 x.__eq__(y)

__ne__(self, other)定义不等号的行为:x != y 调用 x.__ne__(y)

__gt__(self, other)定义大于号的行为:x > y 调用 x.__gt__(y)

__ge__(self, other)定义大于等于号的行为:x >= y 调用 x.__ge__(y)

 算数运算符

__add__(self, other)定义加法的行为:+

__sub__(self, other)定义减法的行为:-

__mul__(self, other)定义乘法的行为:*

__truediv__(self, other)定义真除法的行为:/

__floordiv__(self, other)定义整数除法的行为://

__mod__(self, other)定义取模算法的行为:%

__divmod__(self, other)定义当被 divmod() 调用时的行为

__pow__(self, other[, modulo])定义当被 power() 调用或 ** 运算时的行为

__lshift__(self, other)定义按位左移位的行为:<<

__rshift__(self, other)定义按位右移位的行为:>>

__and__(self, other)定义按位与操作的行为:&

__xor__(self, other)定义按位异或操作的行为:^

__or__(self, other)定义按位或操作的行为:|

 反运算

__radd__(self, other)(与上方相同,当左操作数不支持相应的操作时被调用)

__rsub__(self, other)(与上方相同,当左操作数不支持相应的操作时被调用)

__rmul__(self, other)(与上方相同,当左操作数不支持相应的操作时被调用)

__rtruediv__(self, other)(与上方相同,当左操作数不支持相应的操作时被调用)

__rfloordiv__(self, other)(与上方相同,当左操作数不支持相应的操作时被调用)

__rmod__(self, other)(与上方相同,当左操作数不支持相应的操作时被调用)

__rdivmod__(self, other)(与上方相同,当左操作数不支持相应的操作时被调用)

__rpow__(self, other)(与上方相同,当左操作数不支持相应的操作时被调用)

__rlshift__(self, other)(与上方相同,当左操作数不支持相应的操作时被调用)

__rrshift__(self, other)(与上方相同,当左操作数不支持相应的操作时被调用)

__rxor__(self, other)(与上方相同,当左操作数不支持相应的操作时被调用)

__ror__(self, other)(与上方相同,当左操作数不支持相应的操作时被调用)

 增量赋值运算

__iadd__(self, other)定义赋值加法的行为:+=

__isub__(self, other)定义赋值减法的行为:-=

__imul__(self, other)定义赋值乘法的行为:*=

__itruediv__(self, other)定义赋值真除法的行为:/=

__ifloordiv__(self, other)定义赋值整数除法的行为://=

__imod__(self, other)定义赋值取模算法的行为:%=

__ipow__(self, other[, modulo])定义赋值幂运算的行为:**=

__ilshift__(self, other)定义赋值按位左移位的行为:<<=

__irshift__(self, other)定义赋值按位右移位的行为:>>=

__iand__(self, other)定义赋值按位与操作的行为:&=

__ixor__(self, other)定义赋值按位异或操作的行为:^=

__ior__(self, other)定义赋值按位或操作的行为:|=

 一元操作符

__neg__(self)定义正号的行为:+x

__pos__(self)定义负号的行为:-x

__abs__(self)定义当被 abs() 调用时的行为

__invert__(self)定义按位求反的行为:~x

 类型转换

__complex__(self)定义当被 complex() 调用时的行为(需要返回恰当的值)

__int__(self)定义当被 int() 调用时的行为(需要返回恰当的值)

__float__(self)定义当被 float() 调用时的行为(需要返回恰当的值)

__round__(self[, n])定义当被 round() 调用时的行为(需要返回恰当的值)

__index__(self)1. 当对象是被应用在切片表达式中时,实现整形强制转换

2. 如果你定义了一个可能在切片时用到的定制的数值型,你应该定义 __index__

3. 如果 __index__ 被定义,则 __int__ 也需要被定义,且返回相同的值

 上下文管理(with 语句)

__enter__(self)1. 定义当使用 with 语句时的初始化行为

2. __enter__ 的返回值被 with 语句的目标或者 as 后的名字绑定

__exit__(self, exc_type, exc_value, traceback)1. 定义当一个代码块被执行或者终止后上下文管理器应该做什么

2. 一般被用来处理异常,清除工作或者做一些代码块执行完毕之后的日常工作

 容器类型

__len__(self)定义当被 len() 调用时的行为(返回容器中元素的个数)

__getitem__(self, key)定义获取容器中指定元素的行为,相当于 self[key]

__setitem__(self, key, value)定义设置容器中指定元素的行为,相当于 self[key] = value

__delitem__(self, key)定义删除容器中指定元素的行为,相当于 del self[key]

__iter__(self)定义当迭代容器中的元素的行为

__reversed__(self)定义当被 reversed() 调用时的行为

__contains__(self, item)定义当使用成员测试运算符(in 或 not in)时的行为

封装

将不同的方法,封装到一个类里面从而完成一个功能。

继承

将父类的属性和方法给子类使用

私有的属性,不能通过对象直接访问,但是可以通过方法访问

私有的方法,不能通过对象直接访问

私有的属性、方法,不会被子类继承,也不能被访问

一般情况下,私有的属性、方法都是不对外公布的,往往用来做内部的事情,起到安全的作用

父类中的 私有方法、属性,不会被子类继承

可以通过调用继承的父类的共有方法,间接的访问父类的私有方法、属性

单继承

子类在继承的时候,在定义类时,小括号()中为父类的名字

父类的属性、方法,会被继承给子类

demo 

class F(): #定义父类

    def func(self):

        print("rookie yu")

class S(F): #子类继承

    pass   

S.func()

上边的代码我们可以看到,子类完全没有写任何方法,但是我们可以调用fcun方法,就是因为继承父类。

当我们使用子类的时候,有的时候子类的方法名和父类相同,那么就会重写父类的方法,再次调用的时候回调用子类的方法,不会调用父类写的方法。

class F(): #定义父类

    def func(self):

        print("rookie yu")

class S(F): #子类继承

    def func():

        print("rookie yu sun")

s = S()

s.func()

我们可以看到,当我们使用时,直接使用的就是子类的方法

当我们的方法和父类不一样的时候,那么就是给子类增加方法。那时候我们的子类既有父类的方法属性,也有自己独特的方法和属性。

super

当我们使用子类的时候重写了父类的方法,同时还需要父类的方法,那么我们就需要使用super

demo:

class F(): #定义父类

    def func(self):

        return "rookie yu"

class S(F): #子类继承

    def func():

        name =super(S,self).func()   #调用父类方法

        # name =super().func()    #可以简写

        print(name)

S.func()

多层继承

多层继承和单继承相差不多,咱们在上边的例子中S也相当于一个多层继承,因为F类继承的就是object

多继承

多继承这主要是子类对多个类的继承,相当于独生子女可以继承父亲和母亲的所有家产一样,当然还可以有自己的独立的方法和属性。

class A():

    def test1(self):

        print('----A test----')

# 定义一个父类

class B():

    def test2(self):

        print('----B test----')

# 定义一个子类,继承自A、B

class C(A,B):

    pass

obj_C = C()

obj_C.test1()

obj_C.test2()

print(C.__mro__)#可以查看C类的对象搜索方法时的先后顺序

然而当我们的父类都有同一个方法的时候我们调用的时候到底调用的是哪一个父类的方法呢?

那么我就就要看继承的顺序了,当我们继承的第一个父类中有所有要调用的方法,那么就会使用,如果没有那么就去第二个父类调用。

Mixin扩展类

class F(object): #定义父类

    def func(self):

        print("rookie yu")

class MyMixin(object):  #定义扩展类,继承object

    def minxinFunc(self): #扩展类定义方法

        self.func()

class S(MyMixin,F): #定义子类 继承F, MyMixin

    pass

s = S()

s.minxinFunc() #我们调用MyMixin中的minxinFunc方法

在上面的代码中我们可以看到我们的MyMixin类中没有func方法,MyMixin继承的是object,object也不可能有func方法。但是我们用的却是self.func()却执行到了,就是因为子类在继承的时候继承了两个父类F类中有func方法,解释器在解析时,在调用方法时,记录了F类中的方法,MyMixin就可以使用到这个方法了。

多态

多态的概念是应用于Java和C#这一类强类型语言中,而Python崇尚“鸭子类型”。

所谓多态:定义时的类型和运行时的类型不一样,此时就成为多态

class F1(object):

    def show(self):

        print('F1.show')

class S1(F1):

    def show(self):

        print('S1.show')

class S2(F1):

    def show(self):

        print('S2.show')

# 为了让Func函数既可以执行S1对象的show方法,又可以执行S2对象的show方法,所以,定义了一个S1和S2类的父类

# 而实际传入的参数是:S1对象和S2对象

def Func(obj):

"""Func函数需要接收一个F1类型或者F1子类的类型"""

    obj.show()

s1_obj = S1()

Func(s1_obj)# 在Func函数中传入S1类的对象 s1_obj,执行 S1 的show方法,结果:S1.show

s2_obj = S2()

Func(s2_obj)# 在Func函数中传入Ss类的对象 ss_obj,执行 Ss 的show方法,结果:S2.show

其他(内部类)

class Wapper(): #定义一个外部类

    def wFunc(self):  

        print("外部类的方法")

    class Inner(): #定义一个内部类

        def func(self):  #内部类的方法

            print("我是内部类")

w = Wapper()  #创建一个类对象

i = w.Inner()   #创建一个内部类对象

i.func()   #调用内部类方法

内部类和外部类关系就像汽车和车轮,汽车是一个类,轮胎也可以看做一个类。虽然内部类在外部类里面,但是内部类不能直接使用外部类的方法和属性。外部类可以定义一些类属性,在内部类创建对象进而使用。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,736评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,167评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,442评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,902评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,302评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,573评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,847评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,562评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,260评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,531评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,021评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,367评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,016评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,068评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,827评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,610评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,514评论 2 269

推荐阅读更多精彩内容