为了更好地理解静态方法在Python中的工作方式,我开发了这个简短的测试/示例代码。

class TestClass:

def __init__(self, size):

self.size = size

def instance(self):

print("regular instance method - with 'self'")

@staticmethod

def static():

print("static instance method - with @staticmethod")

def static_class():

print("static class method")

a = TestClass(1000)

a.instance()

a.static()

TestClass.static_class()

此代码工作正常,不会返回任何错误。我的问题是:

我是否正确地理解"self"可以理解为"这个方法将从实例中调用"?

再说一遍,@staticmethod背后的逻辑是什么-是创建可以从实例调用的静态方法吗?这不正是静态方法的意义吗?

为什么第二种方法比第三种方法更受欢迎?(我假设由于存在装饰器,所以有一点需要说明。)第三个选项似乎更简单、更直接。

请注意,这在2.x中根本不起作用,而a.static_class()在2.x中也不起作用。

在测试用例中添加TestClass.static()和a.static_class(),观察会发生什么。这可能有助于说明为什么@staticmethod是有用的。

"这不正是静态方法的意义吗?"-能够在实例上调用它的好处是,cls.whatever()和self.whatever()将正常工作,允许您将类名保留在类和实例方法之外,并正确处理继承。

python中类方法差异可能重复:绑定、未绑定和静态

这是一篇关于静态方法的文章。综上所述:

实例方法:需要实例作为第一个参数

类方法:要求类作为第一个参数

静态方法:不需要作为第一个参数

关于你的问题:

对。虽然变量名self是一种约定,但它属于实例。

静态方法可用于将类似的实用方法分组到同一类下。

对于类中的方法,您要么需要将self添加为第一个参数,要么用@staticmethod修饰该方法。"没有参数的非修饰方法将导致错误。

当用参数调用时,可以更清楚地看到这些是如何工作的。修改后的示例:

class TestClass:

weight = 200                             # class attr

def __init__(self, size):

self.size = size                     # instance attr

def instance_mthd(self, val):

print("Instance method, with 'self':", self.size*val)

@classmethod

def class_mthd(cls, val):

print("Class method, with `cls`:", cls.weight*val)

@staticmethod

def static_mthd(val):

print("Static method, with neither args:", val)

a = TestClass(1000)

a.instance_mthd(2)

# Instance method, with 'self': 2000

TestClass.class_mthd(2)

# Class method, with `cls`: 400

a.static_mthd(2)

# Static method, with neither args: 2

总的来说,您可以从访问的角度考虑每个方法:

如果需要访问实例或实例组件(例如实例属性),请使用实例方法,因为它将self作为第一个参数传递。

同样,如果需要访问类,请使用类方法。

如果对实例和类的访问都不重要,则可以使用静态方法。

注意,在上面的示例中,每个方法类型都传递相同的参数,但是通过self和cls对实例和类属性的访问不同。

注意,有一种方法可以使用self.__class__从实例方法访问类组件,从而避免了对类方法的需要:

...

def instance_mthd2(self, val):

print("Instance method, with class access via `self`:", self.__class__.weight*val)

...

a.instance_mthd2(2)

# Instance method, with class access via `self`: 400

参考:我建议看RaymondHettinger的Talkpython的类开发工具包,它用示例清楚地阐明了每种方法类型的用途。

我的例子中的static_class()是您定义为类方法的吗?

不完全是这样。用@classmethod装饰,将cls作为第一个参数传递。然后它将是一个类方法。

方法作用于调用它们的实例。实例作为第一个参数传递,通常称为self。

类方法类似,但作用于整个类对象,而不是其中一个实例。它们作为构造函数和工厂函数,或者配置设置和其他同时影响类或其所有实例的情况,而不是单个实例,都非常方便。

第三个选项,静态方法,是奇数。它们既不传递实例也不传递类。它们有利于在程序的类结构中为组织目的嵌套实用程序功能,但在某种方式上(对代码审阅者、"linting"和程序检查工具等)明确表示您有意不依赖实例或类值。这样,就不会得到关于未使用的self的"已声明但从未使用的变量"警告。

从调用者的角度来看,静态方法与任何其他方法调用类似。如果您没有可用的@staticmethod,那么您可以使用一个普通的实例或类方法(尽管可能存在过量"变量未使用"的风险)。!"过梁警告)。因此,与类方法不同,静态方法是Python的一个完全可选的部分。它们不向语言添加任何功能;相反,它们提供了一种使开发人员的意图更清晰的方法。

以下是您问题的答案:

问题1:

Do I understand correctly that"self" can be understood as something like"this method will be called from an instance"?

不,那不完全是True。self表示函数的第一个参数应该是类的实例。例如:

def my_class_function(self)

可以称为:

self.my_class_function()

OR,

my_class_function(self)

此外,不必使用self作为对类的对象的引用。您可以使用任何东西(只要它是有效变量),但是使用self是所有地方都遵循的标准。

问题2:

Then again, what's the logic behind @staticmethod - is it to create static methods which can be called from an instance? Isn't that exactly not what static methods are about?

@staticmethod变量用于函数中不需要引用类对象的函数,即不使用self访问类的任何属性或函数。

问题3:

Why would the second approach be favored over the third one? (I assume that since the decorator exists, there is a point to this.) The 3rd option seems to be the simpler and more straightforward.

使用第二种方法,即使用@staticmetod,您可以使用类的对象从类外部调用函数,而不像使用第三种方法(不使用decorator),因为函数的范围在类内。

python staticmethod有什么意义_关于静态方法:python中的@staticmethod有什么意义?相关推荐

  1. python如何初始化对象数组_如何理解Python中的面向对象编程?

    (由Python大本营付费下载自视觉中国) 作者 | Radek Fabisiak 译者 | 弯月,责编 | 郭芮 出品 | CSDN(ID:CSDNnews) 现如今面向对象编程的使用非常广泛,本文 ...

  2. 计算机编程导论python程序设计答案-学堂在线_计算机科学与Python编程导论_作业课后答案...

    学堂在线_计算机科学与Python编程导论_作业课后答案 答案: 更多相关问题 近代中国完全沦为半殖民地半封建社会的标志是:A.<马关条约>B.<辛丑条约>C.<凡尔赛和 ...

  3. python将字符串逆序_为什么说Python是一门伟大的入门语言?(附免费教程)

    Python 是一门伟大的入门语言.作为一门伟大的编程语言,一定要具备一些特征,其中有五项特征是非常重要的: 非常棒的首次体验:就像书的开始,首先一定要能够"沉迷",学习新知识一定 ...

  4. python游戏小项目简单_[简单学Python] 通过一个小游戏完成Python入门[2]变量和赋值...

    变量和赋值 到这里,你已经成功地打印出了千寻的名字和卖身契.与此同时,千寻也成为了汤婆婆的工人,渐渐地,她忘记了自己是谁,遗失了自己"姓名"的信息. 那么,在信息纷繁的代码世界里, ...

  5. python wx窗口无法关闭_菜鸟学Python,双手奉上老司机给上路新手总结的Python实战问题…...

    针对Python这一话题每天后台都会有不少小伙伴提出问题,下面我就将这些问题进行汇整,产出"Python实战问题篇",我认为这些问题非常具有代表性,希望可以帮到大家. 第一类问题: ...

  6. python write 写多行_如何用 Python 执行单行命令

    一般来说,面对日常处理的一些小任务,直接用 sed,grep 之类的就可以搞定,更复杂一点的就会考虑 awk 或者用一些现成的轮子,要是 awk 搞不定我就只好用 Python 了.但有些时候,我仅仅 ...

  7. 开源的商业意义_为开源项目提供资金具有良好的商业意义

    开源的商业意义 在商业中,投资期望回报. 那么,开源软件的投资回报率是多少? 人们并不总是很清楚,为什么像Divio这样的公司(需要获利的企业)会愿意捐赠给开源社区和项目. 捐钱并不是人们对商业计划的 ...

  8. 简述python程序的书写规范_简明的 Python 编程规范

    简明的 Python 编程规范 使用编码规范编写程序,不仅可以别人让后面维护的人更方便,同时也方便自己检查程序.以下是百分网小编精心为大家整理的简明的 Python 编程规范,希望对大家编写程序有所帮 ...

  9. python最难的地方_最令人头疼的 Python 问题

    Python中由于使用了全局解释锁(GIL)的原因,代码并不能同时在多核上并发的运行,也就是说,Python的多线程不能并发,很多人会发现使用多线程来改进自己的Python代码后,程序的运行效率却下降 ...

  10. python运行界面如何缩小_如何使用Python调整图像大小

    作者|Nicholas Ballard 编译|VK 来源|Towards Data Science 可以说,每一个"使用计算机的人"都需要在某个时间点调整图像的大小.MacOS的预 ...

最新文章

  1. listen函数的第二个参数_【图像处理】OpenCV系列十七 --- 几何图像变换函数详解(一)...
  2. java排队叫号_java多线程(4)模拟排队叫号程序,不能出现交替执行的结果
  3. 探索Flutter_Image显示Webp逻辑
  4. java设置并行度_控制Java并行流的并行度
  5. 程序员经典面试题,高并发系统,一般需要怎么做
  6. CSDN创始人蒋涛出席2021 中关村论坛,启动“科创中国”开源创新榜单评选
  7. 性能测试篇 :Jmeter HTTP代理服务器录制压力脚本
  8. vm安装windows出问题:加载驱动程序 缺少计算机所需的介质驱动程序。这可能是DVD,U盘或者硬盘驱动程序如果你有包含该驱动程序的CD,DVD或U盘,请立即插入 注意:如果windows安装介..
  9. 两直线平行交叉相乘_十字交叉法解析
  10. matlab处理fits文件,读取 FITS 文件中的数据
  11. 解密网页加密的两个方法
  12. bzoj1921: [Ctsc2010]珠宝商
  13. 柠檬的45种生活妙用
  14. 计算机毕设(附源码)JAVA-SSM快递代收系统
  15. C/S 和 B/S 模式的区别与联系
  16. c语言错误 243什么意思,c语言编译后[Error] stray apos;\243apos; in program
  17. 微信小程序开发类似微博回复功能自带云开发数据库(无限回复)
  18. 国家lpv9服务器包括哪些项目,ipv6与ipv9什么关系
  19. uTools的插件使用
  20. 报告上、下集 |《认文识字●中文字信息精准化》

热门文章

  1. Kubernetes 微服务监控体系
  2. 剪了 20% 的刘海、120Hz 刷新率、1TB 存储,iPhone 13 来了!
  3. 北森完成2.6亿美金融资,一体化×低代码引领HR数字化风潮
  4. 你可能也会掉进这个简单的 String 的坑
  5. 大麦云原生边缘计算探索,让观众剧院看戏也能实现个性化
  6. 一文了解 Spring Boot 服务监控,健康检查,线程信息,JVM堆信息,指标收集,运行情况监控!...
  7. BAT 力捧的 AI 项目再次爆发,这些程序员都受影响!
  8. linux ps2键盘驱动,通用键盘鼠标模拟(包括USB和PS2)
  9. java 两个sql文_Java和SQL取两个字符间的值
  10. 服务器重启后发现docker-compose的nginx重启失败: Error starting userland proxy: listen tcp 0.0.0.0:80: bind: addres