Python学习笔记六(面向对象,类,对象,魔法方法)

面向对象

什么是面向对象?

面向对象时一种思想,是基于面向过程的。

面向过程:面向过程需要程序员自己处理每一步的操作,就像是炒菜一样,需要准备好各种蔬菜,洗菜,切菜,打开煤气灶,放上锅,倒油。。。等等,直到菜出锅你都要知道,都要自己操作。

面向对象:如果用面向对象来描述炒菜应该是这样的。你要炒菜,但是你不会,你不会不要紧,你有钱是个壕,你找到一个厨师,对他说你要吃满汉全席。厨师走了,忙了一个中午,回来告诉你满汉全席做好了,可以用膳了。

从上面的两种炒菜方式可以看出来面向过程注重的内部细节(炒菜的整个流程),面向对象注重的是结果(菜炒出来了就行,怎么炒的我不关心)。

面向对象时基于面向过程的怎么理解?

还是用上面的炒菜来说明一下,现在我是壕,你是厨师,我不会做菜可以,因为我是壕。你不会做菜不可以,你不会做菜你还是厨师吗?你是厨师,所以你会做菜。那么作为厨师你就需要知道怎么洗菜,切菜,打开煤气。。。。等等。

面向过程和面向对象是密不可分的。


光说面向对象,对象是啥?哪里来的?说到这就需要提到另一个概念

什么是类?

人以类聚,物以群分。类,类似,相似。程序中的类就是把一些就有相似功能的方法和属性放到一起,组成的一个小的功能集合,就叫做类,类是抽象的。

类的定义

定义格式

class 类名:  # class关键字
    方法列表

类的构成

类名
属性
方法

class People:  # 创建一个类
    pass

对象

什么是对象?

面向对象,在程序中都是现有类后又对象的,为什么呢?因为对对象是类的一个具体存在。就像你,你是人类,是人类的一个具体的存在,具体的实例,所以一个类的具体的实例又叫做实例对象。同理,对象的方法以及属性,分别叫做实例方法以及实例属性。

创建实例对象

创建对象的过程:

class People:  # 首先创建一个类
    pass

# 创建类的一个实例,也就是对象,为了方便使用对象,将对象赋值给变量dragon_fang 
dragon_fang = People()  

对象的实例属性和实例方法

人类有一些特征,比如姓名、年龄、性别等。除了这些特征,人类还有很多行为,比如可以思考、可以奔跑、可以吃饭等。

这些描述性的特征就是一个对象的属性,而行为动作就是对象的方法。

class People:
    def cogitate(self):
        print("认真思考。。。")

    def run(self):
        print("可以跑步。。。")

    def eat(self):
        print("可以吃饭。。。")


dragon_fang = People()
dragon_fang.name = "DragonFang"
dragon_fang.age = 100
print("name:%s ,age:%d " % (dragon_fang.name, dragon_fang.age))

dragon_fang.cogitate()
dragon_fang.run()
dragon_fang.eat()

对象的属性和方法

通过 对象.属性 的方式可以直接为对象添加一个属性或者使用属性的值,对象.方法()的方式可以直接调用对象的方法。

self 形参,self 是一个形参,代表了调用方法的对象。虽然形参是可以任意命名的,但是为了规
范,这里建议使用self。

self 的使用

既然self 是实例对象的引用,name可不可以在实例方法中通过self 获取实例对象的实例属性?答案是可以的

class People:
    def cogitate(self):
        print("认真思考。。。")

    def run(self):
        print("可以跑步。。。")

    def eat(self):
        print("可以吃饭。。。")

    def show(self):  # 增加自我介绍方法
        print("name:%s ,age:%d " % (self.name, self.age))


dragon_fang = People()
dragon_fang.name = "DragonFang"
dragon_fang.age = 100

dragon_fang.cogitate()
dragon_fang.run()
dragon_fang.eat()
dragon_fang.show()

# 结果:
# 认真思考。。。
# 可以跑步。。。
# 可以吃饭。。。
# name:DragonFang ,age:100  # show()方法正常执行了

创建多个对象

class People:
    def cogitate(self):
        print("认真思考。。。")

    def run(self):
        print("可以跑步。。。")

    def eat(self):
        print("可以吃饭。。。")


dragon_fang = People()
dragon_fang.name = "DragonFang"
dragon_fang.age = 100
print("name:%s ,age:%d " % (dragon_fang.name, dragon_fang.age))

dragon_fang.cogitate()
dragon_fang.run()
dragon_fang.eat()

xiao_ming = People()  # 创建另一个People类的对象,赋值给xiao_ming

# 创建了xiao_ming 打印一下xiao_ming 的属性 
print("name:%s ,age:%d " % (xiao_ming.name, xiao_ming.age))

结果信息:

运行结果

22行报错,People 类没有属性 name 。创建第一个对象的时候添加了属性,dragon_fang 的属性可以正常使用, 创建第二个对象的时候说没有 name 属性,说明了什么? 说明对象的属性是各自独立的,不共享的。


魔法方法

魔法方法 _init_(self)

python官方提供了很多的魔法方法,魔法方法在恰当的时机,会自动执行。_init(self) 就是其中之一,注意魔法方法两侧各有两条下划线 “_” ,_init(self) 方法也是一样。(附官方说明:Called after the instance has been created (by new()), but before it is returned to the caller.)

_init(self) 方法的作用是初始化。通过self引用的实力对象为每一个实例添加属性。因为self 引用了调用方法的实例对象,由此可以得出_init(self) 方法的执行是在创建对象之后。

class People:
    def __init__(self):
        self.name = "DragonFang"
        self.age = 18

    def show(self):
        print("name:%s ,age:%d " % (self.name, self.age))


dragon_fang = People()
dragon_fang.show()

xiao_ming = People()
xiao_ming.show()

# 结果为:
# name:DragonFang ,age:18 
# name:DragonFang ,age:18 

怎么让每个实例对象的名字不相同呢?传参,通过给_init_(self)传参初始化每个实例对象的name、age。

class People:
    def __init__(self, name, age):
        self.name = name
        self.age = age 

    def show(self):
        print("name:%s ,age:%d " % (self.name, self.age))


dragon_fang = People("DragonFang", 19)
dragon_fang.show()

xiao_ming = People("xiaoMing", 20)
xiao_ming.show()

# 结果为:
# name:DragonFang ,age:19 
# name:xiaoMing ,age:20 

魔法方法_Str_(self)

魔法方法_Str_(self) 的作用是打印对象的描述信息,必须有返回值,且返回值必须是字符串。(附官方说明:Called by str(object) and the built-in functions format() and print() to compute the “informal” or nicely printable string representation of an object. The return value must be a string object.)

class People:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def show(self):
        print("name:%s ,age:%d " % (self.name, self.age))

    def __str__(self):
        return "name:%s ,age:%d " % (self.name, self.age)


dragon_fang = People("DragonFang", 19)
dragon_fang.show()
print(dragon_fang)
 
# 结果为:
# name:DragonFang ,age:19 
# name:DragonFang ,age:19  

需要注意 _str(self) 必须有返回值,而且返回值的类型必须是字符串类型,否则报错。
所以 _str
(self) 的作用一般是用来打印对象的描述信息。

魔法方法_del_(self)

魔法方法_del_(self) 当对象即将被销毁的时候执行。(附官方说明:Called when the instance is about to be destroyed)

什么情况下对象会被销毁?

  • 程序结束
  • 对象的所有引用被删除

_del_(self) 方法的作用,

  • 因为del(self) 方法在对象即将被销毁时调用,所以可以验证对象是否被销毁。
  • 因为del(self) 方法在对象即将被销毁时调用,所以也可以做一些其他操作,比如释放资源。

数据的保护

使用对象.属性可以在类的外部修改属性的值,但是这种修改方式不安全。

class People:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def __str__(self):
        return "name:%s ,age:%d " % (self.name, self.age)


dragon_fang = People("DragonFang", 19)
dragon_fang.age = -500
print(dragon_fang)

# 结果为:
# name:DragonFang ,age:-500  # 这是传说中的向天再借五百年吗?


怎样确保数据的正确性呢?方法,通过方法设置可以确保数据的正确性。

class People:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def __str__(self):
        return "name:%s ,age:%d " % (self.name, self.age)

    def set_age(self, new_age):
        if new_age >= 0:
            self.age = new_age
        print("数据不合法")


dragon_fang = People("DragonFang", 19)
dragon_fang.set_age(-500)
print(dragon_fang)

# 结果为:
# 数据不合法
# name:DragonFang ,age:19 

你可能会虽然通过方法确保了正确,但是依然可以通过对象.属性的方式设置属性的值,该怎么解决呢?私有,使用私有属性,私有属性配合方法使用能更好的保护数据的正确性。通过在属性前加两条下划线“_”的形式将公有属性变成私有属性

class People:
    def __init__(self, name, age):
        self.name = name
        self.__age = age

    def __str__(self):
        return "name:%s ,age:%d " % (self.name, self.__age)

    def set_age(self, new_age):
        if new_age >= 0:
            self.__age = new_age
        print("数据不合法")


dragon_fang = People("DragonFang", 19)
dragon_fang.set_age(-500)
print(dragon_fang)
dragon_fang.__age

Traceback (most recent call last):
File "E:/workspace/pycharm/pycharm/Demo.py", line 18, in <module>
dragon_fang.__age
AttributeError: 'People' object has no attribute '__age'
数据不合法
name:DragonFang ,age:19

报错了,说明在类外不能使用对象.属性名的方式访问私有属性。
不能访问私有属性,能不能访问私有方法?私有方法同样是通过增加两条下划线“_”的形式

class People:
    def __init__(self, name, age):
        self.name = name
        self.__age = age
 
    def __show(self):
        print("name:%s ,age:%d " % (self.name, self.__age))


dragon_fang = People("DragonFang", 19)
dragon_fang.__show()

Traceback (most recent call last):
File "E:/workspace/pycharm/pycharm/Demo.py", line 11, in <module>
dragon_fang.__show()
AttributeError: 'People' object has no attribute '__show'

报错,说明不能再类外通过对象.方法名() 的方式访问私有方法

伪私有

伪,假的。伪私有,不是真正的私有。python中没有真正意义上的私有都是伪私有。
为什么这么说?

class People:
    def __init__(self, name, age):
        self.name = name
        self.__age = age

    def __show(self):
        print("name:%s ,age:%d " % (self.name, self.__age))


dragon_fang = People("DragonFang", 19)
dragon_fang._People__show()

# 结果为:
# name:DragonFang ,age:19 

私有只是解释器在处理私有属性,私有方法的时候改变了属性 或者方法的名字,从而达到私有的目的。仅供了解,仅供了解,仅供了解。强烈不建议使用,强烈不建议使用,强烈不建议使用。


到此结   DragonFangQy   2018.4.10

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

推荐阅读更多精彩内容

  • Python 面向对象Python从设计之初就已经是一门面向对象的语言,正因为如此,在Python中创建一个类和对...
    顺毛阅读 4,218评论 4 16
  • 1.1面向对象 面向对象(object-oriented ;简称: OO)至今还没有统一的概念 我这里把它定义为:...
    TENG书阅读 567评论 0 0
  • 还有半个月,2017年就要结束了,时间总是这样飞快的流逝。 早睡早起方面:基本每天都在5点左右醒来,睡的也越来越早...
    八月芳菲阅读 103评论 0 0
  • 繁世纷杂 扰了月色 灯火连成疲惫的模样 肩上添了沉重的担 连呼吸都有了寂寞的味道 谁的手冰凉 谁的眼涣散 谁的梦 ...
    煦吻静阅读 308评论 0 8
  • 儿时,老屋后面有一大片竹林,郁郁苍苍的。仲夏时分,酷暑难耐,光是站在屋子后头,便能感到满心的阴凉。 竹林是一个卫士...
    符符lalala阅读 548评论 3 1