我是栗子,带大家从零开始学习Python,希望每篇文章都能让你收获满满!
今天我们要说的是面向对象的核心-----类,类能帮我们把复杂的事情变得有条理,有顺序,希望大
家通过学习类能改善自己的编码风格,使代码变得更为好看,更加通俗易懂。
生物有不同的种类,食物有不同的种类,人类社会的种种商品也有不同的种类。但凡可被称之为一
类的物体,他们都有着相似的特征和行为方式。用编程表示就是“类”(class)。
类是有一些系列有共同特征和行为事物的抽象概念的总和。
当我们使用类的时候,首先需要创建一个类。使用关键字class可以做到这点;你还需要给这个类
起个名字和继承关系。
小栗子:
对于可乐来讲,只要是同一个品牌的可乐,他们就有着同样的成分,这被称之为配方。我们用
Python 中的类来表达这件事:
class CocaCola:
formula = ['caffeine','sugar','water','soda']
我们继续按照定义好的配方(类)来生产可乐。只要配方一样味道都是相同的。
coke_for_me = CocaCola()
coke_for_you = CocaCola()
在左边我们创建一个变量,右边写上类的名称,这样看起来很像是赋值的行为,我们称之为类的实例化。而被实例化后的对象,我们称之为实例(instance),或者说是类的实例。
小栗子:
对于可乐来说,按照配方把可乐生产出来的过程就是实例化的过程。
print(CocaCola.formula)
print(coke_for_me.formula)
print(coke_for_you.formula)
运行结果:
>>> ['caffeine','sugar','water','soda']
>>> ['caffeine','sugar','water','soda']
>>> ['caffeine','sugar','water','soda']
在类的名字后面输入 .
,IDE 就会自动联想出我们之前在定义类的时候写在里面的属性,而这就是
类属性的引用(attribute references)。类的属性会被所有类的实例共享,所以当你在类的实例后面
再点上 .
,索引用的属性值是完全一样的。
小栗子:
类的属性与正常的变量并无区别。
for element in coke_for_me.formula:
print(element)
运行结果:
>>> caffeine
>>> sugar
>>> water
>>> soda
在创建了类之后,通过 object.new_atrr
的形式进行一个赋值,于是我们就得到了一个新的实例的变量,实例的变量就是实例变量,而实例变量有一个专有的术语,我们称之为实例属性(Instance Atrribute)。
小栗子:
通过下面的代码,我们给在中国生产的可口可乐贴上了中文字样的“可口可乐”标签,同样的配方,不一样的名称,就带来了不同的效果,中文的可乐变得更加受欢迎!
这说明生产的过程中有必要做一些独有的本地化调整:
class CocaCola:
formula = ['caffeine','sugar','water','soda']
coke_for_China = CocaCola()
coke_for_China.local_logo = '可口可乐' #创建实例属性
print(coke_for_China.local_logo) #打印实例属性引用结果
运行结果:
>>> 可口可乐
类的实例可以引用属性,方法就是函数,但我们把这个函数称之为方法(Method)。
方法是供实例使用的,因此我们还可以称之为实例方法(Instance Method)。
小栗子:
当你喝掉一瓶可乐的时候,你会从咖啡因和大量的糖分中获得能量,如果使用类的方法来表示可乐的这个“功能”的话,那应该是这样的:
class CocaCola:
formula = ['caffeine','sugar','water','soda']
def drink(self):
print('Energy!')
coke = CocaCola()
coke.drink()
运行结果:
>>> Energy!
我知道你现在的关注点一定在这个奇怪的地方——似乎没有派上任何用场的 self
参数。我们来说明一下原理,其实很简单,我们不妨修改一下代码:
class CocaCola:
formula = ['caffeine','sugar','water','soda']
def drink(coke): # HERE!
print('Energy!')
coke = CocaCola()
coke.drink()
运行结果:
>>> Energy!
怎么样,现在有些头绪了吧?和你想的一样,这个参数其实就是被创建的实例本身!就是将一个个对象作为参数放入函数括号内。
再进一步说,一旦一个类被实例化,那么我们其实可以同样使用原来的方式:
coke = CocaCola
coke.drink() == CocaCola.drink(coke) #左右两边的写法完全一致
被实例化的对象会被编译器默默地传入后面方法的括号中,作为第一个参数。
上面这两种方法是一样的,但是我们更多地会写成前面那种形式。
其实 self
这个参数名称是可以随意修改名称的(编译器并不会因此而报错),但是按照 Python 的
规矩,我们还是统一使用 self
。
时代在变迁,可乐的种类也在变化我们按照最新的来定于:
class CocaCola:
calories = 140
sodium = 45
total_carb = 39
caffeine = 34
ingredients = [
'High Fructose Corn Syrup',
'Carbonated Water',
'Phosphoric Acid',
'Natural Flavors',
'Caramel Color',
'Caffeine'
]
def __init__(self,logo_name):
self.local_logo = logo_name
def drink(self):
print('You got {} cal energy!'.format(self.calories))
不同的本地化策略和新的种类的开发,使得生产并非仅仅是换个标签这么简单了,包装、容积、甚至是配方都会发生变化,但唯一不变的是:它们永远是可口可乐。
所有的子品类都会继承可口可乐的品牌,Python 中类自然也有对应的概念,叫做类的继承
(inheritance),我们拿无咖可乐(CAFFEINE-FREE)作为例子:
class CaffeineFree(CocaCola):
caffeine = 0
ingredients = [
'High Fructose Corn Syrup',
'Carbonated Water',
'Phosphoric Acid',
'Natural Flavors',
'Caramel Color',
]
coke_a = CaffeineFree('Cocacola-FREE')
coke_a.drink()
我们在新的类 CaffeineFree 后面的括号中放入 CocaCola,这就表示这个类是继承于 CocaCola 这
个父类的,而 CaffeineFree 则成为了 CocaCola 子类。类中的变量和方法可以完全被子类继承,
但如需有特殊的改动也可以进行覆盖(override)。
可以看到CAFFEINE-FREE存在着咖啡因含量、成分这两处不同的地方,并且在新的类中也仅仅是
重写了这两个地方,其他没有重写的地方,方法和属性都能照常使用。
哈哈哈 !文写到这里结束了,下一篇入门到实战的系列大概率会写第三方模块的一些东西,如果
有这方面还不是很清楚的小可爱,可以提前预约下~
欢迎一起学习交流、往期的文章内容项目素材源码等都可以滴滴我~