zoukankan      html  css  js  c++  java
  • Python

    实例方法

    在类中定义的方法默认都是实例方法,前面几篇文章已经大量使用到实例方法

    实例方法栗子

    class PoloBlog:
        def __init__(self, name, age):
            print("自动调用构造方法")
            self.name = name
            self.age = age
    
        def test(self):
            print("一个实例方法,需要通过对象调用")
            print("my name is :", self.name, " and my age is :", self.age)
    
    
    blog = PoloBlog("小菠萝", 24)
    blog.test()
    
    
    # 输出结果
    自动调用构造方法
    一个实例方法,需要通过对象调用
    my name is : 小菠萝  and my age is : 24 
    • 最少也要包含一个 self 参数,用于绑定调用此方法的实例对象(Python 会自动完成绑定)
    • 实例方法通常会用实例对象直接调用

    通过类名调用实例方法

    Python 也支持通过类名调用实例方法,但需要手动给 self 参数传实例对象

    blog = PoloBlog("小菠萝", 24)
    
    PoloBlog.test(blog)
    
    
    # 输出结果
    自动调用构造方法
    一个实例方法,需要通过对象调用
    my name is : 小菠萝  and my age is : 24

    假设不传实例对象,pycharm 会有warning

    类方法

    类方法和实例方法很相似,又很不相似

    相似点

    • 也至少要包含一个参数,不过通常命名为 cls
    • 在调用类方法时,无需显式为 cls 参数传参,但传递的并不是实例对象,而是类对象本身

    不同点

    最大的不同在于需要使用 @classmethod 装饰器才能称为类方法

    实际栗子

    class PoloBlog:
        # 类属性
        sum = 0
    
        # 类方法, 添加装饰器
        @classmethod
        def class_func(cls):
            print("class_func cls 对象的 id ", id(cls))
            cls.sum += 1
            print("类属性 sum ", cls.sum)
    
        @classmethod
        def class_func_twi(cls):
            print("class_func_twi cls 对象的 id ", id(cls))
            cls.sum += 1
            print("类属性 sum ", cls.sum)
    
    
    PoloBlog.class_func()
    PoloBlog.class_func_twi()
    
    
    # 输出结果
    class_func cls 对象的 id  140583542774880
    类属性 sum  1
    class_func_twi cls 对象的 id  140583542774880
    类属性 sum  

    cls 代表的是同一个对象,类对象

    类方法可以调用实例方法吗?

    可以,但有局限性

    class PoloBlog:
        # 类属性
        sum = 0
    
        def __init__(self, sum):
            self.sum = sum
    
        # 实例方法
        def test(self):
            print("self id is ",id(self))
            print("self 对象的 sum 属性值为:", self.sum)
    
        # 类方法, 添加装饰器
        @classmethod
        def class_func(cls):
            print("cls id is ", id(cls))
            print("类属性 sum ", cls.sum)
            # 调用实例方法
            cls.test(cls)
    
    
    PoloBlog.class_func()
    
    
    # 输出结果
    cls id is  140500501817184
    类属性 sum  0
    self id is  140500501817184
    self 对象的 sum 属性值为: 0
    • 类方法调用实例方法的方式: cls.实例方法(cls) ,通过 cls 调用,且还要传递 cls 为参数
    • 从 id 相同即可看出,实例方法接收的仍然是一个类对象

    实例对象可以调用类方法吗?

    可以,但不建议

    blog = PoloBlog(2)
    blog.class_func()
    
    
    # 输出结果
    cls id is  140500501817184
    类属性 sum  0
    self id is  140500501817184
    self 对象的 sum 属性值为: 0 
    • blog 是一个实例对象,且初始化赋值了 sum 实例属性
    • 但最后实例方法打印的仍然是 sum 类属性,表明类方法无法访问实例属性
    • 且 cls、self 参数的 id 和上面的栗子完全一样,表明即使通过实例对象调用类方法,传递的仍然是类对象的引用,所有类方法都被同一个类对象调用,一个类只有一个类对象

    实例方法可以调用类属性吗?

    可以,但不能通过实例对象调用,只能通过类对象

    class PoloBlog:
        # 类属性
        name = "类啊类属性"
    
        def __init__(self, name):
            self.name = name
    
        # 实例方法
        def test(self):
            # 错误栗子
            # print(name)
    
            # 访问的仍然是实例属性
            print(self.name)
    
            # 通过类名访问
            print(PoloBlog.name)
    
    
    blog = PoloBlog("小菠萝")
    blog.test()
    
    
    # 输出结果
    小菠萝
    类啊类属性

    假设直接调用 name 变量可以吗

    肯定不行,报错

    扩展思考题!

    • 一个方法内部既需要访问实例属性,又需要访问类属性,应该定义为什么方法?
    • 答案:实例方法,因为可以通过 类对象.类属性 来访问,但在类方法中无法访问实例属性

    代码栗子直接看上面一个就是啦!

    静态方法

    • 和之前学过的函数一毛一样,唯一区别是:静态方法需要定义在类体中,且需要添加 @staticmethod 装饰器
    • 静态方法没有 self、cls 参数,也不需要至少传一个参数,和普通函数一样
    • Python 解释器不会对它包含的参数做任何类或对象的绑定,所以静态方法无法调用任何类属性、类方法、实例属性、实例方法,除非通过类名和实例对象

    什么时候会用静态方法

    类里面封装的方法

    • 既不需要访问实例属性、实例方法
    • 也不需要访问类属性、类方法

    就可以考虑将这个方法封装成一个静态方法

    实际栗子

    class PoloBlog:
    
        # 静态方法
        @staticmethod
        def info(name, age):
            print(name, age)
    
    
    # 通过类对象调用
    PoloBlog.info("小菠萝111", 24)
    
    blog = PoloBlog()
    # 通过实例对象调用
    blog.info("小菠萝222", 14)
    
    
    # 输出结果      
    小菠萝111 24
    小菠萝222 14

    关于实例方法、 classmethod 和 staticmethod 的实际应用场景

    简单来说

    • 实例方法:方法内部需要访问实例属性、实例方法就定义为实例方法;既需要访问实例属性、方法,也需要访问类属性、方法,那必须定义为实例方法
    • 类方法:方法内部只需要访问类属性、类方法就定义为类方法
    • 静态方法:方法内部既不需要访问实例属性、实例方法,也不需要访问类属性、类方法就定义为静态方法

    也可以参考这篇文章

    待我实战后再来完善此章节

    https://www.zhihu.com/question/20021164

  • 相关阅读:
    MATLAB计算机视觉与深度学习实战
    硬件创业:从产品创意到成熟企业的成功路线图
    Xcode5 创建模板和UIView 关联XIB
    iOS Development: Proper Use of initWithNibName:bundle: Affects UITableViewController
    自定义UIViewController与xib文件关系深入分析
    UIViewController XIB/NIB加载过程
    ios多视图开发中:xib与UIViewController的关联
    UIAlertView、UIActionSheet兼容iOS8
    Xcode6中怎么添加空工程模板
    [OC Foundation框架
  • 原文地址:https://www.cnblogs.com/poloyy/p/15195539.html
Copyright © 2011-2022 走看看