第五、六周我们一起学习了Python的函数,相信你一定可以体会到,使用函数编程能够让代码更加清晰,使用起来也更加方便。

从本周开始,我们将一起来探讨一种全新的编程方式:面向对象编程,来学习“类与对象”的相关内容。

类和实例也是Python基础内容的最后一个“硬骨头”,我们将拿出两到三周的时间来讲解这部分内容。

类和实例在Python世界占据很重要的位置,是你审视整个Python世界的一双眼睛,掌握了这部分内容,对于很多代码的理解和应用(特别是对模块的理解和应用)都会有很大的帮助。

老师在这里强调一下,即便是暂时不理解这部分内容,也不影响对我们最后项目的挑战。一定要认真坚持到我们课程的最后,这样才能在你脑海里构建起整个Python的知识体系。

两种编程方式

面向过程的编程方式

在前面的学习中,我们学习了如何使用函数来实现一些功能,更重要的是如何利用函数实现代码复用。现在,我们试着使用这种函数式编程的方式,来实现一个做蛋炒饭的功能。

我们不必写出代码实现的细节,只要一 一列举做蛋炒饭的具体步骤或者过程就可以了。它大概可以这样来表示:

def egg_fried_rice():1.买鸡蛋、米饭等食材2.蒸熟米饭3.炒鸡蛋……

当然,每一个过程还可以细分成一系列的子过程,比如“炒鸡蛋”这个过程可以分成生火、倒油、放盐、放葱花…

这种使用函数将具体过程依次表达出来的编程方式叫做面向过程编程或者叫做结构化编程。面向过程编程方法的提出和普及解决了人类历史上的第一次软件危机。

然而,随着硬件的飞速发展和业务需求的日渐复杂,单纯依赖面向过程的编程方法越来越显得效率低下,并且不符合人类的逻辑思维习惯。这直接导致了第二次软件危机的爆发。

面向对象编程

二十世纪七十年代,先后出现了两门语言——SIMULA67和Smalltalk,成功将面向对象编程的思想引入到程序设计中,彻底颠覆了人类的编程习惯,也解决了第二次软件危机。

面向对象编程的精髓是把物体、行为等看成一个个的类,这些类通常包含一些属性和实现某些功能的能力(封装性);并且一些功能相似的类具有某些特定的联系(继承性和多态性)。

例如,我们可以把做蛋炒饭这个事情定义为蛋炒饭类,这个类有一些属性,比如鸡蛋和米饭的数量;还有一些功能,比如蒸米饭、炒鸡蛋等。

这就把做蛋炒饭的一些要素封装到蛋炒饭类里面了。从此之后,我们在做蛋炒饭的时候,只需要用蛋炒饭这个类构造一个做蛋炒饭的实例(也叫作对象)就可以了。

做蛋炒饭跟做海鲜炒饭步骤差不多,它们可以由一个更加广义的炒饭类派生出来。因此,我们可以构建这样的关系。

我们把炒饭类叫做蛋炒饭类和海鲜炒饭类的父类,相应地,蛋炒饭类和海鲜炒饭类叫做炒饭类的子类,蛋炒饭类和海鲜炒饭类互为兄弟类。

我们很容易理解,蛋炒饭类和海鲜炒饭类都遵循炒饭类的基本步骤,这种遵从方式就叫做继承性;但是它们又有各自的特点(比如食材不同、翻炒时间不同等),这种独特的特性就叫做多态性。

我们再来讲一个更加符合人类认知的例子。我们知道,老虎和猫都属于猫科动物,猫科动物和犬科动物都属于哺乳动物。那么这些类之间的关系可以用下图来表示。

猫类和猫科动物类是什么关系

  • 猫类是猫科动物类的父类
  • 猫类是猫科动物类的子类
  • 猫类是猫科动物类的爷爷类
  • 猫类是猫科动物类的孙子类

图中,虚线左边的类关系相信你已经很清楚了。我们现在来讨论如何利用类创建实例

用一句话来概括就是,类是实例的模板,实例是类的具体化。

我们可以利用类这个模板,构造出无数个实例;这些实例之间可能有某些微小的差异(如老虎的体重、体长、花纹等),但是基本特征符合对应类的特征(比如四肢行走、能够捕猎、能够吼叫等)。

我们用一张图来表述类、实例与面向对象编程的基本概念和特性。

总结两种编程方式的主要内容(找同学回答)

从定义类到构造实例

定义类

现在,我们来定义一个最简单的类,按照上一小节的逻辑,类名就叫FelidAnimal(猫科动物的英文单词)吧。

就像函数用def定义一样,类也有自己的定义关键词,叫做class,因此定义类的语法是:

到这里,Python里面所有的“体”我们都已经接触到了。它们是 if判断语句下面的判断体for和while语句下面的循环体def下面的函数体class下面的类体

体的概念很重要,它决定着一些变量的作用域。忘记作用域是什么的同学,可以回去复习一下第五周“函数概念和应用”的内容。这里补充汇总一下:

回到我们的课程中,我们继续来看对类的定义。类命名一般要遵循驼峰法,这里的ClassName就是用的驼峰法命名。

驼峰法的意思是如果类名里有多个单词,那每个单词的首字母要大写,这样,整个类名看起来就像骆驼的峰背一样凹凸起伏。我们对猫科动物类的命名也是遵循驼峰法,叫做FelidAnimal。

前面内容已经介绍了体的概念,接下来看ClassName后面括号里面的内容,这里排列了几个FatherClass, 意思是ClassName这个类继承自FatherClass1,FatherClass2…这些父类。

关于类的继承我们将在后续会统一讲解,这里你只需要记得,父类写在括号里,并且可以继承多个父类。

在当前类不继承任何父类的时候,括号里可以什么也不写,这时当前类默认继承Python的根类,叫做object,同样地,我们在后面的课程中统一讲解。

现在,我们可以创建一个猫科动物类了。

class FelidAnimal():pass
print(FelidAnimal)
<class '__main__.FelidAnimal'>

现在我们还没有对猫科动物类定义任何东西,所以暂时使用占位符pass来保证语法不出错。

占位符是一个很常用的命令,在我们的编码过程中,如果还没想好一些“体”是用来干什么的时候,可以暂时使用占位符来替代,表示暂时什么都不做。

使用print( )函数打印FelidAnimal,发现它是一个类class,这样一来,我们已经成功地定义了一个类,虽然这个类暂时还没有实现任何功能。

构造实例

进一步的我们可以使用FelidAnimal( )构造一个实例并使用变量my_animal表示,构造实例的语法是实例名 = 类名( ). 实例名、方法名、类名也是遵循变量的命名规则,类名也要遵循驼峰命名法。
代码展示:

class FelidAnimal():pass
# 构造实例
my_animal = FelidAnimal()
# 打印实例信息
print(my_animal)
<__main__.FelidAnimal object at 0x0000024D93B59BC8>

打印出实例信息后,显示它是FelidAnimal object,at后面的信息是指这个变量存在了计算机内存的具体位置,我们不用深究。

到目前为止,我们已经成功定义了一个类,并且利用这个类构造了一个实例。但是似乎这个类什么用都没有,不要着急,精彩继续。

为了让实例能够具有一些基本属性,我们使用构造方法。

运行下面代码,体会构造方法。不要着急,老师会马上给你讲解。

class FelidAnimal():def __init__(self,further1,height,weight):self.further = further1self.height = heightself.weight = weightfelid_animal1 = FelidAnimal(further='yellow',height=1.2,weight=250)
print("猫科动物1的颜色是:%s" % felid_animal1.further)
print("猫科动物1的身高是:%f" % felid_animal1.height)
print("猫科动物1的体重是:%f" % felid_animal1.weight)
猫科动物1的颜色是:yellow
猫科动物1的身高是:1.200000
猫科动物1的体重是:250.000000

看起来已经有那么点意思了。 我们一起来解析一下构造方法。

构造方法的函数名也必须是_init_(注意:前后分别两个下划线),是英文单词initial(初始化)的缩写。

需要明确一点:在类体中,所有与实例相关的变量都要加上self.,意思是使用self.来访问实例的变量或者方法,也就是说self本身是表示你具体化的实例

所以对于构造方法_init_()(注意:前后分别两个下划线),它的第一个参数必须是self, 以此来说明他是用于构造实例的实例方法。

关于实例方法的更多内容,老师会在下一关为你慢慢讲解。现在,先让我们把注意力放在构造方法上。

除了固定的名字和self参数外,构造方法还可以任意添加其它参数。因为构造方法的本质还是一个函数,所以参数的规则也和函数一致。

在猫科动物类的构造方法里,我们添加了三个参数,分别是further,height和weight,它们就是函数中的形式参数。

相应地,在构造实例的时候,我们传入了"yellow"、1.2和250三个实参值。 构造方法使用以下三个赋值语句:

self.further = further
self.height = height
self.weight = weight

把这三个值分别赋值给了self.further、self.height和self.weight。

这里需要注意的是,self.further中的further不是指的参数further,而是实例变量further, 我们完全可以把实例变量命名成别的名字,比如:

def __init__(self, further, height, weight):self.pimao = furtherself.shengao = heightself.tizhong = weight``````python
class FelidAnimal():def __init__(self,further,height,weight):self.pimao = furtherself.shenggao = heightself.tizhong = weightfelid_animal1 = FelidAnimal(further='yellow',height=1.2,weight=250)
print("猫科动物1的颜色是:%s" % felid_animal1.pimao)
print("猫科动物1的身高是:%f" % felid_animal1.shenggao)
print("猫科动物1的体重是:%f" % felid_animal1.tizhong)
猫科动物1的颜色是:yellow
猫科动物1的身高是:1.200000
猫科动物1的体重是:250.000000

但是一般而言,为了让读代码的人更加清楚,我们还是按照实例中的命名方式把实例变量和参数命名成相同的名字。

例子中,我们分别打印出了实例的皮毛、身高和体重,这体现了我们怎样来使用实例。

具体而言,我们可以使用实例名字.实例变量名字来表示实例的变量,比如felid_animal1.further。

现在,轮到你来:请定义一个猫类,猫具有姓名、年龄、皮毛、身高、体重五个特征。使用定义的猫类构造两个实例,它们的特征如下:

姓名:Tom, 年龄:2, 皮毛:white,身高:0.4,体重:2.1

姓名:Jerry, 年龄:3, 皮毛:yellow,身高:0.5,体重:3.2

class Cat():def __init__(self, name, age, further, height, weight):# 补充以下五行代码,分别把参数值赋值给实例变量self.name1=nameself.age1=ageself.further1=furtherself.height1=heightself.weight1=weight
# 构造第一个实例,self就是tom_cat
tom_cat = Cat("Tom", 2, "white", 0.4, 2.1)
# 补充一行代码,构造第二个实例,self就是jerry_cat
jerry_cat=Cat("jerry",3,"black",0.5,3.0)
print("%s的毛发是%s" % (tom_cat.name, tom_cat.further1))
print("%s的毛发是%s" % (jerry_cat.name, jerry_cat.further1))

总结一下怎样定义类和构造实例。

从实例变量到类变量

实例变量

关于实例变量,刚刚在介绍构造方法的时候我们已经接触过了。

可以这样认为,在类体里面,使用self.实例变量名进行命名的变量都是实例变量。

比如猫类中,姓名、年龄、皮毛、身高、体重等都是实例变量。

当然,不只是构造方法中会出现实例变量,在其它实例方法中也会有实例变量,同样地,我们稍后在讲解实例方法时讲解。

实例变量之所以叫实例变量,是因为它只是作用于实例层级的,而不是类层级的。

我们说过,类是实例的模板,如果一个变量作用于模板上(也就是作用于类上),它将对所有的实例起作用;而实例变量仅仅对某个实例起作用。

具体来说,使用刚才Tom猫和Jerry猫的例子,我们尝试改变Tom猫的实例变量值,然后看看Jerry猫的相应值有没有改变。

抄写下面代码到代码框中,然后运行。

class Cat():def __init__(self, name, age, further, height, weight):self.name = nameself.age = ageself.further = furtherself.height = heightself.weight = weight
tom_cat = Cat("Tom", 2, "white", 0.4, 2.1)
jerry_cat = Cat("Jerry", 3, "yellow", 0.5, 3.2)
print("%s原来的体重是%f" % (tom_cat.name, tom_cat.weight))
print("%s原来的体重是%f" % (jerry_cat.name, jerry_cat.weight))
tom_cat.weight = 2.5
print("%s现在的体重是%f" % (tom_cat.name, tom_cat.weight))
print("%s现在的体重是%f" % (jerry_cat.name, jerry_cat.weight))
class Cat():def __init__(self, name, age, further, height, weight):self.name = nameself.age = ageself.further = furtherself.height = heightself.weight = weight
tom_cat = Cat("Tom", 2, "white", 0.4, 2.1)
jerry_cat = Cat("Jerry", 3, "yellow", 0.5, 3.2)
print("%s原来的体重是%f" % (tom_cat.name, tom_cat.weight))
print("%s原来的体重是%f" % (jerry_cat.name, jerry_cat.weight))
#访问实例变量,实例名.实例变量,修改实例名.实例变量=XX
tom_cat.weight = 2.5
tom_cat.name="Tom1"
print("%s现在的体重是%f" % (tom_cat.name, tom_cat.weight))
print("%s现在的体重是%f" % (jerry_cat.name, jerry_cat.weight))
Tom原来的体重是2.100000
Jerry原来的体重是3.200000
Tom1现在的体重是2.500000
Jerry现在的体重是3.200000

我们发现,修改了Tom的体重后,它的实例变量tom_cat.weight发生了相应的改变;但是这种改变没有影响到Jerry。

相信你已经知道我接下来要说什么了,没错,类变量可以对所有实例造成影响。下面就让我们一起来学习一下类变量。

类变量

类变量在两个地方定义,一个是在类方法中,另一个是在类的方法(注意是类的方法不是类方法,类的方法包括静态方法、实例方法和类方法,我们稍后讲解)之外。

还是用例子说话。我们知道,所有的猫都是四条腿,所以我们在猫类中添加一个类变量:leg_number, 并改变leg_number的值(虽然这在现实中是不会发生的),来看看所有实例是怎么变化的。

抄写并运行下面代码,体会类变量的改变会对实例变量产生什么样的影响。

class Cat():leg_number = 4def __init__(self, name, age, further, height, weight):self.name = nameself.age = ageself.further = furtherself.height = heightself.weight = weight
tom_cat = Cat("Tom", 2, "white", 0.4, 2.1)
jerry_cat = Cat("Jerry", 3, "yellow", 0.5, 3.2)
print("%s原来的腿数量是%i" % (tom_cat.name, tom_cat.leg_number))
print("%s原来的体重是%i" % (jerry_cat.name, jerry_cat.leg_number))
Cat.leg_number = 3
print("哦,所有的猫咪发生了变异,%s现在的腿数量是%i" % (tom_cat.name, tom_cat.leg_number))
print("哦,所有的猫咪发生了变异,%s现在的腿数量是%i" % (jerry_cat.name, jerry_cat.leg_number))
class Cat():#类变量leg_number = 4def __init__(self, name, age, further, height, weight):self.name = nameself.age = ageself.further = furtherself.height = heightself.weight = weight
tom_cat = Cat("Tom", 2, "white", 0.4, 2.1)
jerry_cat = Cat("Jerry", 3, "yellow", 0.5, 3.2)
print("%s原来的腿数量是%i" % (tom_cat.name, tom_cat.leg_number))
print("%s原来的体重是%i" % (jerry_cat.name, jerry_cat.leg_number))
#通过类名.类变量=XX修改类变量
Cat.leg_number = 3
print("哦,所有的猫咪发生了变异,%s现在的腿数量是%i" % (tom_cat.name, tom_cat.leg_number))
print("哦,所有的猫咪发生了变异,%s现在的腿数量是%i" % (jerry_cat.name, jerry_cat.leg_number))
Tom原来的腿数量是4
Jerry原来的体重是4
哦,所有的猫咪发生了变异,Tom现在的腿数量是3
哦,所有的猫咪发生了变异,Jerry现在的腿数量是3

在代码中,我们在类的方法之外定义了类变量leg_number, 然后使用Cat.leg_number = 3 改变了它。 这之后所有实例的leg_number也都变成了3。

再举一个更加常用的例子。 请你编写代码:建立一个银行账户类,类变量是利率,值为0.05;实例变量是用户名、身份证号、密码和存款数量。

利用银行账户类构造两个银行账户实例,首先打印出这两个实例的利率,在利率增加了1个百分点后,再次打印,查看变化。

抄写下面的代码到代码框中,完成本练习。

class BankAccount():interest_rate = 0.05def __init__(self, name, id, password, money):self.name = nameself.id = idself.password = passwordself.money = money
tom_account = BankAccount("Tom", "12345", "000000", 1000)
jerry_account = BankAccount("Jerry", "54321", "888888", 2000)
print("对于%s来说,原来的利率是%f" %(tom_account.name, tom_account.interest_rate))
print("对于%s来说,原来的利率是%f" %(jerry_account.name, jerry_account.interest_rate))
BankAccount.interest_rate = BankAccount.interest_rate + 0.01
print("对于%s来说,现在的利率是%f" %(tom_account.name, tom_account.interest_rate))
print("对于%s来说,现在的利率是%f" %(jerry_account.name, jerry_account.interest_rate))
class BankAccount():interest_rate = 0.05def __init__(self, name, id, password, money):self.name = nameself.id = idself.password = passwordself.money = money
tom_account = BankAccount("Tom", "12345", "000000", 1000)
jerry_account = BankAccount("Jerry", "54321", "888888", 2000)
print("对于%s来说,原来的利率是%f" %(tom_account.name, tom_account.interest_rate))
print("对于%s来说,原来的利率是%f" %(jerry_account.name, jerry_account.interest_rate))
BankAccount.interest_rate = BankAccount.interest_rate + 0.01
print("对于%s来说,现在的利率是%f" %(tom_account.name, tom_account.interest_rate))
print("对于%s来说,现在的利率是%f" %(jerry_account.name, jerry_account.interest_rate))
对于Tom来说,原来的利率是0.050000
对于Jerry来说,原来的利率是0.050000
对于Tom来说,现在的利率是0.060000
对于Jerry来说,现在的利率是0.060000

这下你明白了吧,类变量能够作用于所有的实例。

当然,不管是类变量还是实例变量,都不是一成不变的。

你可以在类体之外增加类变量和实例变量,同样地,增加的类变量会作用于全部实例;增加的实例变量只能对当前实例起作用。

运行下列代码,打印出来的值分别是:

class BankAccount():interest_rate = 0.05def __init__(self, name, this_id, password, money):self.name = nameself.this_id = this_idself.password = passwordself.money = money
tom_account = BankAccount("Tom", "12345", "000000", 1000)
jerry_account = BankAccount("Jerry", "54321", "888888", 2000)
BankAccount.open_bank = "鄞州银行"
tom_account.age = 18
print(tom_account.open_bank)
print(jerry_account.open_bank)
print(jerry_account.age)
  • 鄞州银行,鄞州银行,18
  • 鄞州银行,鄞州银行,报错
  • 鄞州银行,报错,18
  • 鄞州银行,报错,报错
class BankAccount():interest_rate = 0.05def __init__(self, name, this_id, password, money):self.name = nameself.this_id = this_idself.password = passwordself.money = money
tom_account = BankAccount("Tom", "12345", "000000", 1000)
jerry_account = BankAccount("Jerry", "54321", "888888", 2000)
BankAccount.open_bank = "鄞州银行"
tom_account.age = 18
print(tom_account.open_bank)
print(jerry_account.open_bank)
print(jerry_account.age)
鄞州银行
鄞州银行---------------------------------------------------------------------------AttributeError                            Traceback (most recent call last)<ipython-input-15-3e5d45cf87bb> in <module>12 print(tom_account.open_bank)13 print(jerry_account.open_bank)
---> 14 print(jerry_account.age)AttributeError: 'BankAccount' object has no attribute 'age'

代码创建了一个银行账户类BankAccount,然后创建了tom_account和jerry_account两个实例。利用代码BankAccount.open_bank = “鄞州银行"增加了类变量open_bank为"鄞州银行”, 因此,两个实例的open_bank都是"鄞州银行";利用代码tom_account.age = 18,增加了实例变量,该变量只作用于tom_account,jerry_account不受影响,仍然没有实例变量age,因此打印jerry_account.age会报错,错误类型会是:AttributeError: ‘BankAccount’ object has no attribute ‘age’。

选择题中,因为实例jerry_account本来没有实例变量age,所以使用jerry_account.age会报错。

有同学肯定会有这样的疑问:我能知道类和实例都有哪些类变量和实例变量么?

当然可以(毕竟Python无所不能)。 还记得前面讲的,Python的类都默认继承自object类,因此也继承了这个类的一些特有的方法和变量,我们称之为魔法方法和魔法变量。

事实上,我们刚才讲的构造函数_init_()就是魔法家族之一。

魔法家族里的魔法方法和魔法变量有一个共同的特点,都是以两个下划线开头,以两个下划线结尾的。

其中有一个魔法变量是_dict_,代表的是所有的类变量或者实例变量。

运行下列代码,看看银行账户类都有哪些类变量,银行账户实例都有哪些实例变量。

class BankAccount():interest_rate = 0.05def __init__(self, name, id, password, money):self.name = nameself.id = idself.password = passwordself.money = moneytom_account = BankAccount("Tom", "12345", "000000", 1000)
print("类变量有%s"% BankAccount.__dict__)
print("实例变量有%s" % tom_account.__dict__)
类变量有{'__module__': '__main__', 'interest_rate': 0.05, '__init__': <function BankAccount.__init__ at 0x0000024D93B5BAF8>, '__dict__': <attribute '__dict__' of 'BankAccount' objects>, '__weakref__': <attribute '__weakref__' of 'BankAccount' objects>, '__doc__': None}
实例变量有{'name': 'Tom', 'id': '12345', 'password': '000000', 'money': 1000}

从运行结果可以看出来, 银行账户类的类变量有 interest_rate ,还有一些其它的一些魔法变量(继承自 object 类); tom_account 实例有 name 、 id 、 password 和 money 四个实例变量。

还有一点必须要说明,虽然我们可以通过在类体之外增加实例变量和类变量,但是Python不建议这样做,因为类应该是封装好的,不应该再在类体之外做改变。

想想看,如果一定要在类体之外增加类变量和实例变量会发生什么?

这要分以下两种情况:

当在类体外增加类变量时,Python会直接为该类增加类变量。

当在类体外增加实例变量时,无论对应的类中是否有该同名类变量,Python都会创建一个同名的实例变量。

我们还是使用银行账户的例子来说明这两点。运行下列代码,观察实例变量和类变量的变化。

class BankAccount():interest_rate = 0.05def __init__(self, name, id, password, money):self.name = nameself.id = idself.password = passwordself.money = money
tom_account = BankAccount("Tom", "12345", "000000", 1000)
print("原来的类变量有%s"% BankAccount.__dict__)
print("原来的实例变量有%s" % tom_account.__dict__)
BankAccount.exchange_rate = 6.66
tom_account.interest_rate = 0.04
tom_account.open_bank = "鄞州银行"
print("现在的类变量有%s"% BankAccount.__dict__)
print("现在的实例变量有%s" % tom_account.__dict__)
原来的类变量有{'__module__': '__main__', 'interest_rate': 0.05, '__init__': <function BankAccount.__init__ at 0x0000024D93B5BC18>, '__dict__': <attribute '__dict__' of 'BankAccount' objects>, '__weakref__': <attribute '__weakref__' of 'BankAccount' objects>, '__doc__': None}
原来的实例变量有{'name': 'Tom', 'id': '12345', 'password': '000000', 'money': 1000}
现在的类变量有{'__module__': '__main__', 'interest_rate': 0.05, '__init__': <function BankAccount.__init__ at 0x0000024D93B5BC18>, '__dict__': <attribute '__dict__' of 'BankAccount' objects>, '__weakref__': <attribute '__weakref__' of 'BankAccount' objects>, '__doc__': None, 'exchange_rate': 6.66}
现在的实例变量有{'name': 'Tom', 'id': '12345', 'password': '000000', 'money': 1000, 'interest_rate': 0.04, 'open_bank': '鄞州银行'}

通过这个例子,我们发现。 原来的类变量(魔法变量除外)只有 interest_rate , 使用代码 BankAccount.exchange_rate = 6.66 后,类变量增加了 exchange_rate 。

原来的实例变量有name、id、password和money,使用代码 tom_account.interest_rate = 0.04 和tom_account.open_bank = "鄞州银行"后,实例变量增加了interest_rate和open_bank, 但是类变量没有影响。

聪明的你一定还有疑问,现在对于实例tom_account来说, 实例变量中有interest_rate, 类变量中也有interest_rate,那我们在使用tom_account.interest_rate,调用的到底是类变量还是实例变量呢?

实际上,当通过实例去调用变量时,Python会先在实例变量中寻找有没有这个变量,如果没有,再到类变量去找。这跟之前讲的模块的寻找路径是类似的。

总结

面向对象编程的内容到这里先告一段落,后面两关还会有更多内容等着大家。到现在你可能还有些迷糊, 没关系,在学习完所有类三周的内容后,老师还会带你做一个梳理和总结。现在先来看看本关的总结吧。

本周总结

面向过程编程:一种以过程为中心的编程方法,以什么正在发生为主要目标进行编程。

面向对象编程:通过定义类和构造实例的方法进行编程,更加符合人类的思维方式。

体:某些特定语法下面的代码块,包括 if判断语句下面的判断体,for和while语句下面的循环体,def下面的函数体和class下面的类体。

封装性:类的三大特性之一,将数据(变量)和操作(功能)封装在一起,变成一个类。

继承性:类的三大特性之一,描述了一种关系,即子类与父类具有相同的数据(变量)和操作(功能)。

多态性:类的三大特性之一,描述了一种关系,即子类与父类具有不同的数据(变量)和操作(功能)。

驼峰法:类名命名的代码规范,使用多个单词命名,每个单词首字母大写。

实例变量:实例的变量,只作用于当前实例。

类变量:类的变量,可作用于全部实例。

魔法变量:object类中前后各有两个下划线的变量,如__dict__变量。

方法:在类体中的函数叫做方法,分为静态方法、实例方法和类方法。

魔法方法:object类中前后各有两个下划线的变量,如构造方法_init_

本周总结
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3kG4zdXy-1588157701843)(本周总结.png)]

作业

作业1

题目要求

构建一个应聘者类,类变量应该包括:

  • 应聘单位: “鄞州金融”
  • 应聘类型: “校园秋招”
  • 实例变量应该包括:
  • 应聘者姓名:字符串类型
  • 应聘者年龄:整型
  • 应聘者性别:字符串类型
  • 应聘岗位:字符串类型
  • 应聘者特长:字符串类型
  • 学历:字典类型,分别存储大专、大学、研究生等
    构造一个实例,并使用for循环打印出它们所有的实例变量。

动手操作

你需要注意以下点:

  • 1、使用class命令来定义类,注意区分类变量和实例变量;
  • 2、在构造方法中,可以使用字典关键字(两个*)的参数来定义学历变量;
  • 3、使用魔法变量__dict__来获取所有的实例变量。

作业2

题目要求:

现在你们的兄弟公司鄞州银行也要招聘,他们公司的HR想直接参考你们的模板,但是你们已经把类封装好了。现在,尝试改变类变量,要求如下:

  • 1、应聘单位改为”鄞州银行”
  • 2、应聘类型改为”社会招聘”
  • 3、新增工作经验要求为3
    为了验证类变量是否修改成功,请遍历出魔法变量之外的所有类变量。

动手实践

你可以将练习1中的代码直接拿过来用,然后实现以下三点:

  • 1、使用类名.变量名来改变或者增加类变量;
  • 2、使用魔法变量__dict__来获取所有类变量的字典;
  • 3、使用if判断字典的键是否以__开头,来排除有魔法变量。

Python面向对象上相关推荐

  1. python 完全面向对象_史上最全的Python面向对象知识点疏理

    原标题:史上最全的Python面向对象知识点疏理 面向对象技术简介 类: 用来描述具有相同的属性和方法的对象的集合.它定义了该集合中每个对象所共有的属性和方法.对象是类的实例.class 类变量:类变 ...

  2. python学习笔记六 初识面向对象上(基础篇)

    python面向对象 面向对象编程(Object-Oriented Programming )介绍 对于编程语言的初学者来讲,OOP不是一个很容易理解的编程方式,虽然大家都知道OOP的三大特性是继承. ...

  3. Python零基础速成班-第9讲-Python面向对象编程(上),对象和类、初始化、继承、重写、多态、类方法、组合

    Python零基础速成班-第9讲-Python面向对象编程(上),对象和类.初始化.继承.重写.多态.类方法.组合 学习目标 修饰器 面向对象编程:对象和类.初始化.继承.重写.多态.类方法.组合 课 ...

  4. Python面向对象基础(上)—Python Day7

    导入 --Python面向对象基础 Python从设计之初就已经是一门面向对象的语言,正因为如此,在Python中创建一个类和对象是很容易的.本章节我们将详细介绍Python的面向对象编程. 面向对象 ...

  5. Python面向对象编程(上)

    Python面向对象编程 面向对象的编程产生的历史原因:由于面向过程编程在构造系统时,无法解决重用,维护,扩展的问题,而且逻辑过于复杂,代码晦涩难懂,因此,人们开始想能不能让计算机直接模拟现实的环境, ...

  6. 这可能是Python面向对象编程的最佳实践

    作者 | 崔庆才 来源 | 进击的Coder(ID:FightingCoder) Python 是支持面向对象的,很多情况下使用面向对象编程会使得代码更加容易扩展,并且可维护性更高,但是如果你写的多了 ...

  7. 第八课.Python面向对象(二)

    类的继承和多态 继承和多态与函数有共同的目的,都是为了减少代码的冗余,提高复用的效率: 根据"Python面向对象(一)"的笔记,我现在定义一个Cinema类: #父类 class ...

  8. Python面向对象编程:类继承和其衍生术语

    Python面向对象编程03:类继承和其衍生术语 前面我们讲到过正则表达式字符等,上一篇分享了面向对象编程和类的结构,最后稍微提到了继承. Python面向对象编程:深度认识类class_ Pytho ...

  9. Python 面向对象 基础

    编程范式概述: 面向过程 和 面向对象 以及函数式编程 面向过程:(Procedure Oriented)是一种以事件为中心的编程思想. 就是分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实 ...

最新文章

  1. 将CAD图纸转换出来的图片怎么设置其为高清JPG格式?
  2. layui 导航收缩代码_pycharm的十个小技巧,让你写代码效率翻倍
  3. layDate控件的使用
  4. Angular 6+ 之新版service
  5. 循环比赛日程表(信息学奥赛一本通-T1325)
  6. 【MySQL】数据库事务处理---MySQL
  7. 消息循环,注册窗口,创建窗口【图解】
  8. C++primer plus第六版课后编程题答案 6.6
  9. 关于Redis的概念
  10. 数据库管理(事务、ACID、并发、封锁、可串行化、隔离)
  11. json规范,平时不注意的特殊符号
  12. c语言输入身高计算标准体重_体质测试 | 身高 / 体重测试评分标准及方法
  13. bios 微星click_msi微星主板bios设置方法
  14. 有关液压的相关知识(1)-螺纹与齿轮泵
  15. GEM TSU Interface Details and IEEE 1588 Support
  16. 迷你考拉仓私人小仓库储物间出租,百米内的智能仓储!
  17. JS统计页面访问时长
  18. linux打开终端的快捷键放大,linux打开终端的快捷键是什么?
  19. 堆栈与动态分配内存空间
  20. 以太网PHY寄存器分析

热门文章

  1. 怎样应聘计算机教师,计算机教师应聘面试的自我介绍-20210613004732.docx-原创力文档...
  2. 深澜系统服务器架构,智圣新创|深澜4K 3a Radius进程故障处理案例
  3. 魅族6.0系统设备(亲测有效)激活Xposed框架的经验
  4. Qt 中获取摄像头图像数据的方法
  5. SSL 2382 k好数(数位dp)
  6. Python项目-Day32-HTML5-语义化标签-智能表单-选择器
  7. ​在线去水印软件网站​
  8. 2023年我国主要城市地铁站点和线路
  9. 破世界纪录了!用Python实现自动扫雷
  10. IOS 剪切、复制、选中的提示为英文改为中文 解决方法