Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >python super()和classmethod

python super()和classmethod

作者头像
orientlu
发布于 2018-09-13 02:57:40
发布于 2018-09-13 02:57:40
84000
代码可运行
举报
文章被收录于专栏:orientluorientlu
运行总次数:0
代码可运行

@(python)

super(type, obj)

子类中定义了同父类同名的函数后,需要显示调用父类函数时,可以通过 super,也可以直接通过父类名,建议使用 super,比如在初始化函数中调用父类初始化方法,尤其在多重继承的情况下 看看例子:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#!/usr/bin/env python
# coding=utf-8

class A:
    def __init__(self):
        print("Enter A")
        super(A, self).__init__()
        print("Leave A")

class B:
    def __init__(self):
        print("Enter B")
        #super(B, self).__init__()
        print("Leave B")

class CA(A):
    def __init__(self):
        print("Enter CA")
        super(CA,self).__init__()
        print("Leave CA")


class CAA(CA, A):
    def __init__(self):
        print("Enter CAA")
        super(CAA,self).__init__()
        print("Leave CAA")

class CB(B):
    def __init__(self):
        print("Enter CB")
        B.__init__(self)
        print("Leave CB")


class CBB(CB, B):
    def __init__(self):
        print("Enter CBB")
        CB.__init__(self)
        B.__init__(self)
        print("Leave CBB")


if __name__ == "__main__":
    print("- New Object CAA")
    caa = CAA()
    print("- New Object CBB")
    cbb = CBB()

上述列子中,两组类关系: CAA->CA->A 采用 super 调用父类函数 CBB->CB->B 直接通过父类名调用其行数

对比运行结果

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
lcd@ubuntu:~/learn/python$ python3 supper_class.py 
- New Object CAA
Enter CAA
Enter CA
Enter A
Leave A
Leave CA
Leave CAA
- New Object CBB
Enter CBB
Enter CB
Enter B   
Leave B
Leave CB
Enter B   -->重复调用了
Leave B
Leave CBB

可以看到,使用super, python 不止保证继承时按顺序调用父类初始化,而且保证每一个类不被重复调用。

classsmethod

python 有三种方式定义类方法: 如下面例子类 A 定义的三个方法,

  • 常规方式定义了 foo,同对象实例绑定,通过对象调用的时候,会通过隐式 self 参数传递类对象实例子;如果直接通过类调用,需要显示传递类实例;
  • @classmethod 方式定义了 class_foo 方法,同类绑定,可以直接通过类名可以直接调用,调用时通过 cls 隐式参数传递类对象。
  • @staticmethod 方式定义的方法和普通函数一样,没有绑定对象,没有传递隐式参,可以通过类实例或者类调用。(属于类的函数,但是不需要访问类,通过后续子类覆盖,更好地组织代码)
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#!/usr/bin/env python
# coding=utf-8
# by orientlu

class A(object):
    def __init__(self):
        print("A init")
        super().__init__()

    def foo(self, x):
        '''绑定对象'''
        print("A exec foo (%s, %d)" %(self, x))

    @classmethod
    def class_foo(cls, x):
        '''绑定类'''
        print("exec class_foo (%s, %d)" %(cls, x))

    @staticmethod
    def static_foo(x):
        '''没有绑定类,对象'''
        print("exec static_foo (%d)" %(x))

class B(object):
    def foo(self, x):
        '''绑定对象'''
        print("exec foo (%s, %d)" %(self, x))

    @classmethod
    def test_class_foo(cls, x):
        '''绑定类'''
        print("exec test_class_foo -2- (%s, %d)" %(cls, x))

    def test_class_foo(self, x):
        '''后面方法覆盖前面的同名方法'''
        print("exec test_class_foo -1- (%s, %d)" %(self, x))


class AA(A):
    def __init__(self):
        print("AA Int")

    def foo(self, x):
        '''覆盖了父类函数'''
        print("AA exec foo (%s, %d)" %(self, x))


class C(AA):
    def __init__(self):
        '''子类定义了方法覆盖了父类,通过super调用到父类函数'''
        super().__init__()
        print("C init")

    def c_fun1(self):
        '''子类没有定义的函数,直接调用父类函数'''
        self.foo(1)

if __name__ == "__main__":

    print("***********************************")
    print("-------")
    a = A()
    a.foo(1)
    a.class_foo(1)
    a.static_foo(1)

    print("-------")
    A.foo(a, 1)
    A.class_foo(1)
    A.static_foo(1)

    print("***********************************")
    b = B()
    b.test_class_foo(1)
    # 以下调用出错,因为classmethod被后面的函数所覆盖了
    #B.test_class_foo(1)
    # 实际存在是后面定义的函数
    B.test_class_foo(b, 1)

    print("***********************************")
    c = C()
    c.c_fun1()

上述代码在 python3 环境下运行的输出 :

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
***********************************
-------
A init
A exec foo (<__main__.A object at 0x7f6af4c36ac8>, 1)
exec class_foo (<class '__main__.A'>, 1)
exec static_foo (1)
-------
A exec foo (<__main__.A object at 0x7f6af4c36ac8>, 1)
exec class_foo (<class '__main__.A'>, 1)
exec static_foo (1)
***********************************
exec test_class_foo -1- (<__main__.B object at 0x7f6af4c36b38>, 1)
exec test_class_foo -1- (<__main__.B object at 0x7f6af4c36b38>, 1)
***********************************
AA Int
C init
AA exec foo (<__main__.C object at 0x7f6af4c36b70>, 1)
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2017.06.16 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
[887]python中@classmethod和@staticmethod
一般来说,要使用某个类的方法,需要先实例化一个对象再调用方法。 而使用@staticmethod或@classmethod,就可以不需要实例化,**直接类名.方法名()**来调用。 这有利于组织代码,把某些应该属于某个类的函数给放到那个类里去,同时有利于命名空间的整洁。
周小董
2020/08/11
3590
python粗谈面向对象(二)
super并不是一个函数,是一个类名,形如super(B, self)事实上调用了super类的初始化函数,产生了一个super对象;Python的多继承类是通过mro的方式来保证各个父类的函数被逐一调用,而且保证每个父类函数只调用一次(如果每个类都使用super),并且按照mro序列一次调用。下面是一个小练习:
py3study
2020/01/17
6670
Python中的@staticmethod和@classmethod的区别
使用classmethods时,对象实例的类作为第一个参数而不是隐式传递self。
BigYoung小站
2020/07/01
8810
python ——面向对象进阶
1.staticmethod和classmethod staticmethod  静态方法: 让类里的方法,直接被类调用,就像正常的函数一样 宝宝,男 博博,女 海娇,男 海燕,女 海东,男 海峰,男 class Student: # f = open('student', encoding='utf-8') def __init__(self): pass @staticmethod def show_student_info(): f
用户1214487
2018/01/23
5990
python-静态方法staticmethod、类方法classmethod、属性方法property
Python的方法主要有3个,即静态方法(staticmethod),类方法(classmethod)和实例方法:
狼啸风云
2019/12/19
2.3K0
python 类
首先super,我们都知道他的意思是继承父类的含义,但是python中继承父类的实现可以直接再括号中写例如ChildA和childB,这两个是一样的
Tim在路上
2020/08/05
1.1K0
Python面试必刷题系列(4)
本篇是python必刷面试题系列的第4篇文章,集中讲解了面试时重点考察的python基础原理和语法特性,如python的垃圾回收机制、多态原理、MRO以及装饰器和静态方法等语法特性。相信认真读完本文,你不仅可以轻松化解类似上面场景中小尴尬,对今后写出更加高效、优雅的代码也有很大帮助。
小萌哥
2020/07/20
7050
Python学习笔记之Super函数
这是个高大上的函数,在python装13手册里面介绍过多使用可显得自己是高手 23333. 但其实他还是很重要的. 简单说, super函数是调用下一个父类(超类)并返回该父类实例的方法. 这里的下一个的概念参考后面的MRO表介绍. help介绍如下: super(type, obj) -> bound super object; requires isinstance(obj, type) super(type) -> unbound super object super(type, type2) ->
Jetpropelledsnake21
2018/06/21
5080
Python,你真的会使用 staticmethod 和 classmethod 吗?
前几天,有一个小伙伴过来问我,Python 中的 @staticmethod、@classmethod、self、cls 分别代表什么意思,自己平时光顾着用,不知道具体的含义?
AirPython
2020/09/04
7.7K0
Python,你真的会使用 staticmethod 和 classmethod 吗?
理解Python中super()
版权声明:博客文章都是作者辛苦整理的,转载请注明出处,谢谢! https://blog.csdn.net/Quincuntial/article/details/88663237
Tyan
2019/05/25
7530
Python面向对象基础
当把number属性变成私有属性__number之后,无法直接访问得到,只能通过get_number和set_number两个函数访问__number属性。
职场亮哥
2020/10/10
1.1K0
Python面向对象基础
Python方法super()
在类的继承中,如果重定义某个方法,该方法会覆盖父类的同名方法,但有时,我们希望能同时实现父类的功能,这时,我们就需要调用父类的方法了,可通过使用 super 来实现,比如: class Animal(object): def __init__(self, name): self.name = name def greet(self): print 'Hello, I am %s.' % self.name class Dog(Animal): de
林清猫耳
2018/04/26
8970
Python基础之(八)类
当类中变量引用的是可变对象是,类属性和实例属性都能直接修改这个对象,从而影响另一方的值。
py3study
2020/01/03
3850
再再肝3天,整理了70个Python面向对象编程案例
Python 作为一门面向对象编程语言,常用的面向对象知识怎么能不清楚呢,今天就来分享一波
周萝卜
2021/11/24
7360
Python 关于面向对象的 6 个问题
2、Python 如何定义 公有/保护/私有 属性/方法?私有是否是真正的私有,这样做的目的是什么?
somenzz
2022/04/07
5890
Python装饰器是个什么鬼?
所谓的装饰器,其实就是通过装饰器函数,来修改原函数的一些功能,使得原函数不需要修改。
MeteoAI
2019/07/30
8980
Python面向对象:杂七杂八的知识点
实在是因为python中对象方面的内容太多、太乱、太杂,在写相关文章时比我所学过的几种语言都更让人"糟心",很多内容似独立内容、又似相关内容,放这也可、放那也可、放这也不好、放那也不好。
py3study
2020/02/10
9580
Python3快速入门(六)——Pyth
面向对象编程(Object Oriented Programing,OOP)是一种编程思想,OOP把对象当成程序的一个基本单元,一个对象包含数据和操作数据的方法。面向对象编程的三大特性如下: A、封装,可以隐藏实现细节,使代码模块化。 B、继承,可以通过扩展已存在的类来实现代码重用,避免重复编写相同的代码。 C、多态,封装和继承的目的都是为了实现代码重用, 而多态是为了实现接口重用,使得类在继承和派生的时候能够保证任何一个类的实例都能正确调用约定好的属性和方法。 面向对象编程通过封装、继承、多态实现了软件工程的重用性、灵活性、扩展性三个目标。
py3study
2020/01/03
1.4K0
Python面向对象
对象查找属性的顺序:先从对象空间找 ------> 类空间找 ------> 父类空间找 ------->…
Dreamy.TZK
2020/04/09
5420
Python new 类方法和 ini
“Python 中的类都是单例模式?” 一天,一同事问我这样一个问题。这是一个奇怪的问题,可能你也这么认为。这里先不做解释,我们先来看看 __new__ 和 __init__ 方法。
py3study
2020/01/06
1.6K0
相关推荐
[887]python中@classmethod和@staticmethod
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验