形象的理解Class的init、self 、@staticmethod、 @classmethod、@property

@staticmethod、@classmethod、@property这几个带@符号的语法是Python里的「语法糖」。这些语法中文常译作「装饰器」,对于没有任何编程经验的新手,这些都是经常难以理解的地方。再有就是类的self参数,新手通常留于表面的认识造成一些误会。

需要说明一下,本教程针对Python3。

要理解这几样,我们先要对Python类有一个认识,让我们先简单回顾一下「类」。

class 类

我们学习编程语言时,了解到语言有面向过程和面向对象之分,可以面向对象的语言一般都是「高级语言」,为什么高级?因为使用更容易,理解更容易,当然这一切都有代价,但那是另一件事情了,我们有机会在说。

「在Python中一切皆对象」这句话估计你也不是头一回听到了。Python中对象最直接的化身便是class语法,中文称之为「类」,让我们基于Python造「一批」Girlfriend(对象)吧。注意:这里我强调了「一批」这个词。

    # 定义类
    class Girlfriend:
        age = 22
        sex = '女'
        size = 'C'

    # 生产几个女朋友
    lili = Girlfriend()
    mimi = Girlfriend()

以上,我们做了这几件事情:

1)我们定义了一个Girlfriend类,用来一会生产女朋友当相好的对象;

2)基于我低俗的品味,女朋友要定义几个属性:年纪要22岁,罩杯要C,为了谨防意外,性别定义清楚是女,免得造出人妖;

3)基于我的承受能力,我实例化了lili和mimi两个女朋友,两个就够了。

通过上述例子,我们回顾了类与实例的关系:类就好比生产具体产品的「模具」或者「模子」,先做好模具,定义好将来生产的产品期望的样子,然后再用实例化语法通过模具生产一些产品。

我可以随时通过「实例 . 属性」这个语法知道女朋友的一些属性值,比如:

    lili.age  # 会得到22这个值
    mimi.age  # 也是22
    lili.size  # C杯

显然,我的两个女朋友年纪、罩杯都是一致的,因为我在定义模具(类)的时候就明确指定了这些属性。

class的init方法和self参数

什么都一样没意思,我希望至少每个妞的发型不要一样,并且我能指定,想要什么发型就造出来什么发型的女朋友。注意,我的需求有一个细节:女朋友的头发是在女朋友造出来后就已经有的。要想实现这个需求细节,意味着必须在生产女朋友的过程中就完成发型的构建。如果你还有印象,应该依稀还记得Python有一个内置的配合class用的方法init。

init的作用很容易理解,就是每次实例化一个类的时候,会默认自动调用执行这个方法,完成这个方法里定义的行为。这正好符合我们上面的需求,即在生产过程中,加一个发型工艺环节。现在我们改造一下模具和生产工艺:

    # 定义类
    class Girlfriend:
        age = 22
        sex = '女'
        size = 'C'
        def __init__(self, hair):
            self.hair = hair
    # 生产几个女朋友
    lili = Girlfriend('乌黑长发')
    mimi = Girlfriend('金黄短发')

我们来检验一下结果:

    lili.age  # 会得到22这个值
    mimi.age  # 也是22
    lili.hair  # 结果是'乌黑长发'
    mimi.hair  # 结果是'金黄短发'

非常好,两个妞发型已经不一样了。

我们已然知道init的作用:在实例化一个类的时候,会默认自动调用这个方法执行。这就是说,我们不必明显的告诉Python去执行这个方法,在运行下面这行代码时,Python已经悄悄自己执行这个方法了:

 lili = Girlfriend('乌黑长发')

需要明显的告诉程序去干什么事情,有一个针对的术语叫「显式」;相对应的,不需要明显的告诉程序去干事情,程序会按照既定的规则自己办好事情叫「隐式」。在以后的文章中,我们将会再看见这些词,请大家理解和记住意思。

显然,init方法被隐式调用了。我们只在定义class时定义了这个方法,但后续并没有显式的调用他,但他确实执行了,帮我的女朋友做好了发型。如前所述,隐式调用是程序按照「既定」的规则办事,既定的意思就是事先都定下来了怎么做,既然如此,就不能随意变更事先定下的细节。因此,init方法的在名称上很特别,init前后各有两根下划线,这种加下划线的方法名你现在只需记得其目的就是不要让你随便改动。所以,init的方法名不能有任何改动,少根下划线都不行。如果改动,则Python不会把改动后的方法当成init方法去隐式调用了。

让我们再来看看self这个参数。当我们在定义类时,显然无法确定后续会造多少个女朋友,也无法确定女朋友的名字,更无法确定她们的发型。所以我们不能再用定义年纪、性别、罩杯类似办法去定义发型,否则只会导致发型千篇一律。基于此,我们用了init方法,在生产过程中完成发型工艺,并在init方法里定义接收两个参数:self和hair,当我们生产女朋友时:

    # 生产几个女朋友
    lili = Girlfriend('乌黑长发')
    mimi = Girlfriend('金黄短发')

对于init工艺,其实我们是这样告诉程序的:

lili和mimi年纪、性别、罩杯都一样

lili的hair是'乌黑长发'

mimi的hair是'金黄短发'

对于「lili的hair是'乌黑长发'」这句话,本质上是在说明「谁的头发是什么发型?」。所以有两层意思:1&

  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值