百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术资源 > 正文

Python | 实例、类方法和静态方法(1)

off999 2024-09-20 22:50 25 浏览 0 评论

在本文中,我将帮助你揭开类方法、静态方法和常规实例方法背后的奥秘。

如果对它们的差异有了直观的理解,那么你将能够编写面向对象的Python程序,以便更清楚地传达某种意图,并且从长远来看更易于维护。

实例、类方法和静态方法概述

我们首先编写一个类,其中包含实例、类方法和静态方法:

class MyClass:
    def method(self):
        return 'instance method called', self

    @classmethod
    def classmethod(cls):
        return 'class method called', cls

    @staticmethod
    def staticmethod():
        return 'static method called'

实例方法

MyClass的第一个方法叫做“方法”,它是一个普通的实例方法,也是你将会在大多数情况下使用的最基本、最简单的方法。该方法接受一个参数self,它在调用该方法时指向MyClass的一个实例(当然,实例方法可以接受的参数不止一个)。

通过self参数,实例方法可以自由地访问同一对象上的属性和其他方法。当涉及到修改对象的状态时,实例方法就非常给力。

实例方法不仅可以修改对象状态,还可以通过self.__class__属性来访问类本身。这就意味着实例方法也可以修改类的状态。

类方法

比较MyClass.method与第二个方法MyClass.classmethod。我用一个@classmethod装饰符把这个方法标记为类方法。

类方法不接受self参数,而是接受一个cls参数。cls参数在调用方法时指向的是类而不是对象实例。

由于类方法只能访问此cls参数,因此它无法修改对象实例的状态——那需要访问self。但是,类方法仍然可以对应用于类的所有实例的类状态进行修改。

静态方法

第三个方法MyClass.staticmethod用一个装饰符@staticmethod标记为静态方法。

这个方法既不接受self参数,也不接受cls参数(但是,它可以接受任意数量的其他参数)。

因此静态方法既不能修改对象状态,也不能修改类状态。静态方法在它们可以访问的数据方面受到限制,它们主要用于对你的方法进行空间命名。

见证它们的作用!

我知道到目前为止,这个讨论是相当理论化的。我相信:对这些方法在实践中的差异有一个直观的理解。我们现在来复习一些具体的例子。

让我们来看看这些方法在被调用时是如何运行的。我们从创建类的实例开始,然后对其调用三个不同的方法。

类MyClass的每个方法,都返回一个元组,元组包含踪迹信息,以及该方法可以访问的类或对象的有关信息。

下面是调用实例方法时发生的情况:

>>> obj = MyClass()
>>> obj.method()
('instance method called', <MyClass instance at 0x101a2f4c8>)

这些代码确认了method(实例方法)可以通过self参数访问对象实例(打印为<MyClass instance>)。

此方法被调用时,Python用实例对象obj替换了self参数。我们可以用句点“.”调用方法的方式(obj.method()),手动传递实例对象来获得相同的结果:

>>> MyClass.method(obj)
('instance method called', <MyClass instance at 0x101a2f4c8>)

你能猜到在不创建实例的情况下调用该方法会怎么样吗?

顺便说一下,实例方法还可以通过self.__class__属性访问类本身。这使得实例方法在访问受限时非常给力 —— 它们可以修改对象实例和类本身的状态。

接下来让我们尝试一下类方法:

>>> obj.classmethod()
('class method called', <class MyClass at 0x101a2f4c8>)

调用classmethod() 向我们展示了它不能访问<MyClass instance>对象,而是只能访问代表类本身的<class MyClass>对象(在Python中,一切皆对象。即使是类本身也不列外)。

请注意,当我们调用MyClass.classmethod()时,Python如何自动将类作为第一个参数传递给函数,通过句点“.”的方式自动实现这种行为,这与实例方法上的self参数的工作方式相同。

将这些参数命名为self和cls只是一种约定。你可以将它们命名为the_object 和the_class,也能得到相同的结果。重要的是,它们在方法的参数列表中处于第一个位置。

现在到了调用静态方法的时候:

>>> obj.staticmethod()
'static method called'

你看到我们如何成功地在对象上调用staticmethod()了吗?某些开发者看到通过实例调用静态方法时会感到惊讶。

在后台,当使用句点“.”的方式调用静态方法时,Python只是通过不传入self或cls参数来执行访问限制。

这就确保静态方法既不能访问对象实例状态,也不能访问类状态。静态方法像普通函数一样工作,但它属于类(和每个实例)的命名空间。

现在,让我们看一看:如果没有预先创建对象实例,就在类本身上调用静态方法时,会发生什么情况:

>>> MyClass.classmethod()
('class method called', <class MyClass at 0x101a2f4c8>)

>>> MyClass.staticmethod()
'static method called'

>>> MyClass.method()
TypeError: unbound method method() must
    be called with MyClass instance as first
    argument (got nothing instead)

我们可以顺利地调用classmethod() 和staticmethod(),但调用实例方法method() 时,显示TypeError异常。

这是意料之中的。这次我们没有创建实例,而是尝试直接通过在类本身调用实例方法。这意味着Python无法填充self参数,因此调用失败。

由上可见这三种方法之间的区别。但我不会就此罢休,在接下来的两部分中,我将介绍两个稍微实际一些的示例,以便大家了解何时使用这些特殊的方法类型。

以这个简单的Pizza类为例:

class Pizza:
    def __init__(self, ingredients):
        self.ingredients = ingredients

    def __repr__(self):
        return f'Pizza({self.ingredients!r})'

>>> Pizza(['cheese', 'tomatoes'])
Pizza(['cheese', 'tomatoes'])

注意:本文中的代码示例使用Python 3.6的f字符串来实现__repr__方法中返回的字符串。在Python2和3.6之前的Python3版本中,你将使用不同的格式化字符串表达式,例如:

def __repr__(self):
        return 'Pizza(%r)' % self.ingredients

未完,待续。。。

相关推荐

第九章:Python文件操作与输入输出

9.1文件的基本操作9.1.1打开文件理论知识:在Python中,使用open()函数来打开文件。open()函数接受两个主要参数:文件名和打开模式。打开模式决定了文件如何被使用,常见的模式有:&...

Python的文件处理

一、文件处理的流程1.打开文件,得到文件句柄并赋值给一个变量2.通过句柄对文件进行操作3.关闭文件示例:d=open('abc')data1=d.read()pri...

Python处理文本的25个经典操作

Python处理文本的优势主要体现在其简洁性、功能强大和灵活性。具体来说,Python提供了丰富的库和工具,使得对文件的读写、处理变得轻而易举。简洁的文件操作接口Python通过内置的open()函数...

Python学不会来打我(84)python复制文件操作总结

上一篇文章我们分享了python读写文件的操作,主要用到了open()、read()、write()等方法。这一次是在文件读写的基础之上,我们分享文件的复制。#python##python自学##...

python 文件操作

1.检查目录/文件使用exists()方法来检查是否存在特定路径。如果存在,返回True;如果不存在,则返回False。此功能在os和pathlib模块中均可用,各自的用法如下。#os模块中e...

《文件操作(读写文件)》

一、文件操作基础1.open()函数核心语法file=open("filename.txt",mode="r",encoding="utf-8"...

栋察宇宙(二十一):Python 文件操作全解析

分享乐趣,传播快乐,增长见识,留下美好。亲爱的您,这里是LearingYard学苑!今天小编为大家带来“Python文件操作全解析”欢迎您的访问!Sharethefun,spreadthe...

值得学习练手的70个Python项目(附代码),太实用了

Python丰富的开发生态是它的一大优势,各种第三方库、框架和代码,都是前人造好的“轮子”,能够完成很多操作,让你的开发事半功倍。下面就给大家介绍70个通过Python构建的项目,以此来学习Pytho...

python图形化编程:猜数字的游戏

importrandomnum=random.randint(1,500)running=Truetimes=0##总的次数fromtkinterimport*##导入所有tki...

一文讲清Python Flask的Web编程知识

刚入坑Python做Web开发的新手,还在被配置臃肿、启动繁琐折磨?Flask这轻量级框架最近又火出圈,凭5行代码启动Web服务的极致简洁,让90后程序员小张直呼真香——毕竟他刚用这招把部署时间从半小...

用python 编写一个hello,world

第一种:交互式运行一个hello,world程序:这是写python的第一步,也是学习各类语言的第一步,就是用这种语言写一个hello,world程序.第一步,打开命令行窗口,输入python,第二步...

python编程:如何使用python代码绘制出哪些常见的机器学习图像?

专栏推荐绘图的变量单变量查看单变量最方便的无疑是displot()函数,默认绘制一个直方图,并你核密度估计(KDE)sns.set(color_codes=True)np.random.seed(su...

如何编写快速且更惯用的 Python 代码

Python因其可读性而受到称赞。这使它成为一种很好的第一语言,也是脚本和原型设计的流行选择。在这篇文章中,我们将研究一些可以使您的Python代码更具可读性和惯用性的技术。我不仅仅是pyt...

Python函数式编程的详细分析(代码示例)

本篇文章给大家带来的内容是关于Python函数式编程的详细分析(代码示例),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。FunctionalProgramming,函数式编程。Py...

编程小白学做题:Python 的经典编程题及详解,附代码和注释(七)

适合Python3+的6道编程练习题(附详解)1.检查字符串是否以指定子串开头题目描述:判断字符串是否以给定子串开头(如"helloworld"以"hello&...

取消回复欢迎 发表评论: