【python基础知识】12.类与对象(二)

类与对象(二)

  • 创建类的两个关键点
    • 特殊参数:self
      • 小结
    • 特殊方法:初始化方法
      • 练习题
  • 结语

创建类的两个关键点

特殊参数:self

正式揭秘特殊参数self的作用:self会接收实例化过程中传入的数据,当实例对象创建后,实例便会代替 self,在代码中运行。

换言之,self 是所有实例的替身,“替身”是什么意思呢?我们来看一个例子。

刚刚我们列举的类方法都只有一个self参数,实际上和一般函数一样,类的方法也可以设置多个参数:(直接运行即可 )

class Chinese:

    name = '大师兄'  # 类属性name

    def say(self, someone):  # 带有两个参数的方法
        print(someone + '是中国人')

person = Chinese()
print(person.name)
person.say('大师兄') 
# self调用时要忽略,'大师兄'传给参数someone

运行结果:

大师兄
大师兄是中国人

这样写虽然没错,但实际上是多此一举,因为只要在say方法内部调用类属性’吴枫’,就可以实现同样的功能,不必重复传参。

怎么在方法内部调用类属性呢?你可能会想着这样写:

# 以下代码会报错
class Chinese:

    name = '大师兄'  # 类属性name

    def say(self):
        print(name + '是中国人')
        # 打印出'大师兄是中国人'
person = Chinese()
person.say()

但这样会报错,系统会告诉你name在say方法中没有被定义,那怎么办呢?
还记得我们刚说的,如果要在类的外部调用类属性,我们得先创建一个实例,再用实例名.属性的格式调用吗?

那么如果想在类的内部调用类属性,而实例又还没创建之前,我们就需要有个变量先代替实例接收数据,这个变量就是参数self。

正确的写法是这样子的:(留意第六行)

class Chinese:

    name = '吴枫'  # 类属性name

    def say(self):     
        print(self.name + '是中国人') #留意这行代码

person = Chinese()   # 创建Chinese的实例person
person.say()         # 调用实例方法

当最后一行代码运行时,实例person会像参数一样传给self,替换掉self,第六行的self.name等价于person.name。

person.name就相当于调用了类属性name(即’大师兄’),然后跑完整个方法。

它的作用相当于:(对比上面的代码,直接运行即可)

class Chinese:

    name = '大师兄'  # 类属性name

    def say(person):     
        print(person.name + '是中国人')

person = Chinese()   # 创建Chinese的实例person
person.say()         # 调用实例方法

运行结果:

大师兄是中国人

可见,self的作用相当于先给实例占了个位置,等到实例创建好就“功成身退,退位让贤”。

同理,如果想在类的方法内部调用其他方法时,我们也需要用到self来代表实例。

阅读代码后点击运行:(重点看第七行)

class Chinese:

    def greeting(self):
        print('很高兴遇见你')

    def say(self):
        self.greeting() #重点看这行代码
        print('我来自中国')

person = Chinese()
# 创建实例person
person.say()
# 调用say()方法

运行结果:

很高兴遇见你
我来自中国

当最后一行实例person调用say()方法时,便会执行say()内部的语句(第七行开始)。

此时self.greeting()就变成person.greeting(),也就是调用实例方法greeting(),打印出’很高兴遇见你’,再打印出’我来自中国’。

小结

综上,所以我们说self代表的是类的实例本身,方便数据的流转。对此,我们需要记住两点:

第一点:只要在类中用def创建方法时,就必须把第一个参数位置留给 self,并在调用方法时忽略它(不用给self传参)。

第二点:当在类的方法内部想调用类属性或其他方法时,就要采用self.属性名或self.方法名的格式。

好,self这个神奇的参数就讲解到这里。对初学者来说,确实不是那么容易理解,如果不熟悉,可以多多温习,多多联系巩固一下哦。
在self的基础上,下面我们来看第二个特殊点:初始化方法(也叫构造函数)

特殊方法:初始化方法

定义初始化方法的格式是def init(self),是由init加左右两边的【双】下划线组成( initialize “初始化”的缩写)。

初始化方法的作用在于:当每个实例对象创建时,该方法内的代码无须调用就会自动运行。

# 阅读代码后直接运行    
class Chinese:

    def __init__(self): 
        print('很高兴遇见你,我是初始化方法')

person = Chinese()

运行结果:

很高兴遇见你,我是初始化方法

是不是很神奇?我们只是创建了实例,还没有调用,初始化方法就自动执行了!

利用这个特性,在编写习惯上,我们会在初始化方法内部完成类属性的创建,为类属性设置初始值,这样类中的其他方法就能直接、随时调用。我们来看个例子:(阅读后直接运行)

class Chinese:
    def __init__ (self):
        self.mouth = 1  # self.不能丢
        self.eye = 2
    
    def body(self):
        print('我有%s张嘴巴' % self.mouth)
        print('我有%s只眼睛' % self.eye)

person = Chinese()
person.body()

运行结果:

我有1张嘴巴
我有2只眼睛

除了设置固定常量,初始化方法同样可以接收其他参数,让传入的这些数据能作为属性在类的方法之间流转。我们再来看个例子:

class Chinese:

    def __init__(self, name, birth, region):
        self.name = name   # self.name = '大师兄' 
        self.birth = birth  # self.birth = '山西'
        self.region = region  # self.region = '北京'

    def born(self):
        print(self.name + '出生在' + self.birth)

    def live(self):
        print(self.name + '居住在' + self.region)    

person = Chinese('大师兄','山西','北京') # 传入初始化方法的参数
person.born()
person.live()

先看14行:

person = Chinese('大师兄','山西','北京') # 传入初始化方法的参数

当初始化方法有多个参数的时候,在实例化的时候就要传入相应的值,这里’大师兄’传给参数name, '山西’传给birth,'北京’传给region。

当实例person创建完成后,初始化方法会自动执行,此时第三行的self.name = name就等价于self.name = ‘大师兄’,以此类推。(self.name中的name可以换成其他名称,只是我们习惯上这么写)

如此一来,类的其他方法就能通过self.属性名的形式调用传入的数据了。(还记得self是实例的替身吧)

我猜你可能会有这样的疑惑:不用初始化方法不是也能实现吗?写多个方法不是更麻烦吗?

确实可以,比如上述的代码,我们也可以这么写:

class Chinese:

    def born(self, name, birthplace):
        print(name + '出生在' + birthplace)

    def live(self, name, region):
        print(name + '居住在' + region)

person = Chinese()
person.born('大师兄','山西')
person.live('大师兄','北京')

虽然代码量并没有减少,但我们可以看到使用初始化方法,至少我们不必重复传参,传入的数据还可以被多次调用,比如这里的’大师兄’。

class Chinese:

    def __init__(self, name, birth, region):
        self.name = name   # self.name = '大师兄' 
        self.birth = birth  # self.birth = '山西'
        self.region = region  # self.region = '北京'

    def born(self):
        print(self.name + '出生在' + self.birth)

    def live(self):
        print(self.name + '居住在' + self.region)    

person = Chinese('大师兄','山西','北京') # 传入初始化方法的参数
person.born()
person.live()

随着我们想实现的功能愈发复杂,我们会在类内部编写很多的方法,如果我们需要传入的数据能在类中长久保存并能被随时调用,初始化方法就是一个不错的解决方案。

等你自己开始用类来写代码时,就会发现初始化方法又实在又好用。所以只要用到了类,一般都少不了它。

练习题

说了这么多,我们来做个小练习吧。请你在下列代码的基础上补充一个初始化方法(其余部分不变),要求最后的打印结果是:你在哪里出生?我出生在山西。

class Chinese:
    def __init__(self,hometown):
        #此处请补充你的代码,达到题目要求
    def born(self):
        print('我出生在%s。' % self.hometown)

dashixiong = Chinese('山西')
dashixiong.born()

看下参考代码,多看多写,慢慢熟悉。

class Chinese:
    # 初始化方法的创建,init两边双下划线。
    def __init__(self, hometown):
        self.hometown = hometown
        print('你在哪里出生?')
    
    def born(self):
        print('我生在%s。' % self.hometown)

dashixiong = Chinese('山西') # 传给参数hometown
dashixiong.born()

再次恭喜~你已经掌握了创建类的两个特殊点。至此,你已经将课堂的主要知识都收入囊中了。

结语

学到这,可能你会觉得类看起来平平无奇,这主要是老师为了让你能快速掌握相关概念和语法,课堂上的案例都很简单,而类一般是用在较复杂的项目里。

所以下一篇文章,我会具体阐述类与实例在实际编程中的应用,也对一开始提出的问题:什么是面向对象编程做一个具体的阐释。
【python基础知识】12.类与对象(二)_第1张图片

你可能感兴趣的:(python,开发语言,前端,程序人生)