Python常见面试题006 类方法、类实例方法、静态方法有何区别?

python,常见,面试题,方法,实例,静态方法,区别 · 浏览次数 : 210

小编点评

**类方法** * 类方法是定义在类中的静态方法。 * 类方法没有访问私有属性和方法。 * 类方法可以被其他类方法调用。 **类实例方法** * 类实例方法是定义在类中的普通方法。 * 类实例方法可以访问私有属性和方法。 * 类实例方法可以被实例对象调用。 **静态方法** * 静态方法是定义在类中的静态方法。 * 静态方法没有访问私有属性和方法。 * 静态方法可以被类实例对象调用。 * 静态方法可以被类本身调用。 **示例** ```python class Human: def __init__(self, name): self.name = name def say(self): print(f'我的名字是{self.name}') @classmethod def walk(cls): print('类方法 walk') @staticmethod def sleep(): print('类静态方法 sleep') class Person: @classmethod def eat(cls): pass def drink(self): pass # 调用类方法 Human.walk() Human.sleep() # 调用实例方法 wuxianfeng = Human('wuxianfeng') wuxianfeng.say() # 调用静态方法 print(Person.f) ```

正文

006. Python中类方法、类实例方法、静态方法有何区别?

全部放一个里面篇幅过大了,就拆分成1个个发布

示例代码

class Human:
    def __init__(self, name):
        self.name = name

    def say(self):
        print(f'我的名字是{self.name}')

    @classmethod
    def walk(cls):
        print('类方法 walk')

    @staticmethod
    def sleep():
        print('类静态方法 sleep')

一般这样调用

# 类名.类方法
Human.walk()

# 实例名.实例方法
wuxianfeng = Human('wuxianfeng')
wuxianfeng.say()

# 静态方法则无所谓
Human.sleep()
wuxianfeng.sleep()

问题就是,实例能否调用类方法?类能否调用实例方法呢?

  • 实例能否调用类方法:能,比如wuxianfeng.walk()

  • 类能否调用实例方法:不能,比如Human.say()

    TypeError: say() missing 1 required positional argument: 'self'
    

cls和self是约定

cls代指类本身,self代指实例

class Person:
    @classmethod
    def eat(cls): # 这里的cls就是指Person
        pass
    def drink(self): # 这里的self就是指Person()出来的实例
        pass

cls和self这2个名字只是约定,见名知义,不建议更改,IDE会给你提示,其他地方需要自己注意,事实上你可以写成任意的名字,但不推荐

class Person:
    @classmethod
    def eat(class_name): 
        print('eat')
    def drink(instance_name):
        print('drink')
Person.eat()   # 没毛病
Person().drink()  # 没毛病

pycharm中的提示信息

官网

@classmethod

把一个方法封装成类方法。

一个类方法把类自己作为第一个实参,就像一个实例方法把实例自己作为第一个实参。请用以下习惯来声明类方法:

class C:
    @classmethod
    def f(cls, arg1, arg2): ...

@classmethod 这样的形式称为函数的 decorator

类方法的调用可以在类上进行 (例如 C.f()) 也可以在实例上进行 (例如 C().f())。 其所属类以外的类实例会被忽略。 如果类方法在其所属类的派生类上调用,则该派生类对象会被作为隐含的第一个参数被传入。

类方法与 C++ 或 Java 中的静态方法不同。 如果你需要后者,请参阅本节中的 staticmethod()

@staticmethod

将方法转换为静态方法。

静态方法不会接收隐式的第一个参数。要声明一个静态方法,请使用此语法

class C:
    @staticmethod
    def f(arg1, arg2, ...): ...

@staticmethod 这样的形式称为函数的 decorator

静态方法的调用可以在类上进行 (例如 C.f()) 也可以在实例上进行 (例如 C().f())。

Python中的静态方法与Java或C ++中的静态方法类似。另请参阅 classmethod() ,用于创建备用类构造函数的变体。

像所有装饰器一样,也可以像常规函数一样调用 staticmethod ,并对其结果执行某些操作。比如某些情况下需要从类主体引用函数并且您希望避免自动转换为实例方法。对于这些情况,请使用此语法:

class C:
    builtin_open = staticmethod(open)

小结

方法 装饰器 参数 调用方
类方法 @classmethod cls 类(推荐),实例(不推荐)
实例方法 self 实例
静态方法 @staticmethod 无默认参数 类(推荐),实例(不推荐)
  1. 定义方式
    1. 类方法和静态方法都是通过装饰器实现的,实例方法不是
  2. 传参
    1. 实例方法需要传入self参数,类方法需要传入cls参数,而静态方法不需要传self或者cls参数
  3. 调用
    1. 实例方法只能通过实例对象调用;类方法和静态方法可以通过类对象或者实例对象调用,如果是使用实例对象调用的类方法或静态方法,最终都会转而通过类对象调用
  4. 应用
    1. 实例方法使用最多,可以直接处理实例对象的逻辑
    2. 类方法不需要创建实例对象,直接处理类对象的逻辑
    3. 静态方法将与类对象相关的某些逻辑抽离出来,不仅可以用于测试,还能便于代码后期维护。
    4. 实例方法和类方法,能够改变实例对象或类对象的状态,而静态方法不能

与Python常见面试题006 类方法、类实例方法、静态方法有何区别?相似的内容:

Python常见面试题006 类方法、类实例方法、静态方法有何区别?

006. Python中类方法、类实例方法、静态方法有何区别? 全部放一个里面篇幅过大了,就拆分成1个个发布 示例代码 class Human: def __init__(self, name): self.name = name def say(self): print(f'我的名字是{self.

Python常见面试题001-005,涉及深浅拷贝、MRO、函数可变参数、作用域、is和==的区别等

Python常见面试题001-005 参考资料 https://github.com/taizilongxu/interview_python https://github.com/hantmac/Python-Interview-Customs-Collection https://github.

Python常见面试题007. 谈谈Python中__init__和__new__的区别

007. 谈谈Python中__init__和__new__的区别 python中关于dunder method双下方法,或magic method魔术方法的描述多在 https://docs.python.org/zh-cn/3.9/reference/datamodel.html#special

Python常见面试题008. 谈谈python中的解包

008. 谈谈python中的解包 这是个简单的知识点,但有的学员并不理解 unpacking解包 解,对应的是*或者**,也有自动解包之说 包对应的可迭代对象 自动解包 赋值的demo a,b = [1,2] print(a) # 1 print(b) # 2 将容器里面的元素逐个取出来分别赋值

Python常见面试题011. 如何在Python中动态创建类?

011. 如何在Python中动态创建类? 说在前面 答案是type 你印象中的type是用来查看对象的类型的 li = [] type(li) # 得到list 对自定义的类是这样的 class Person: pass wuxianfeng = Person() type(wuxianfeng)

Python常见面试题009. 元组和列表有什么区别

009. 元组和列表有什么区别 这个题是简单的,但要拿满分或者说高分不容易 相同点 | 共性 | 说明 | | | | | 可以存放任意元素 | 一般都放同类型 | | 支持索引访问 | 甚至是负数 | | 支持切片操作 | | | 逗号分隔元素 | | | 都是有序集合(容器) | | | 可以随

Python常见面试题010. Python的int占多大内存?

010. Python的int占多大内存? 示例代码 import sys a = 0 print(a.__sizeof__()) # 24 print(sys.getsizeof(a)) # 24 所以答案是24?并不是!看下面 import sys b = 1 print(b.__sizeof_

Python常见面试题012. 可迭代对象和迭代器有啥区别?

012. 可迭代对象和迭代器有啥区别? 2者不是一回事(废话) 比如 from collections.abc import Iterable,Iterator print(isinstance([1, 2], Iterable)) # True 列表是可迭代对象 print(isinstance(

Python常见面试题013.请说出下面的代码返回结果是什么?

013.请说出下面的代码返回结果是什么? *的坑;简单题 参考:https://docs.python.org/zh-cn/3.9/library/stdtypes.html#typesseq 示例代码 lists = [[]] * 3 lists[0].append(1) 请问lists此时是什么

Python常见面试题014.请说出下面的代码返回结果是什么?

示例代码 def fun(a, b, c, d): nums = [] for num in range(a, b): nums.append(lambda: num ** c) return nums[d]() print(fun(1, 5, 2, 0)) print(fun(1, 5, 2, 1