Python 静态方法类方法普通方法

少年已老 · 2021年02月05日 · 2791 次阅读
## 类方法

**普通的方法**

    class A:
        def func(self):
            print(self)


    a1 = A()
    a1.func()
    # 结果:a1的内存地址
    # <__main__.A object at 0x00FACEB0>

**调用普通方法必须要传一个参数**

    class A:
        def func(self):  # 类里面的普通方法
            print(self)

        @classmethod  # 类方法的装饰器
        def fun1(cls):
            print(cls)


    a1 = A()
    a1.func()  # 对象调用self,将对象本身传给self
    A.func(a1)  # 类名点方法,主动传的对象

    #结果
    # <__main__.A object at 0x030E6450>
    # <__main__.A object at 0x030E6450>

**类方法:通过类名调用的方法,类方法中第一个参数约定俗成是cls,python自动将类名(类空间)传给cls**

    class A:
        def func(self):  # 类里面的普通方法
            print(self)

        @classmethod  # 类方法的装饰器
        def func1(cls):
            print(cls)


    A.func1()  # 类名点方法,主动传的对象

    # 结果
    # <class '__main__.A'>

**对象可以调用类方法,传给cls的是类本身。(对象调用普通方法,传给self的是对象实例本身)**

    class A:
        def func(self):  # 类里面的普通方法
            print(self)

        @classmethod  # 类方法的装饰器
        def func1(cls):
            print(cls)


    a1 = A()
    a1.func1()

    #结果
    #<class '__main__.A'>

**类方法应用场景:**
1.类中有些方法是不需要传入对象,不要对象参与。
比如:要实现Alex2

    class A:
        name = "Alex"
        count = 1

        def func1(self):  # 此方法无需对象参与
            return A.name + str(A.count + 1)

方法一

    A.func1(111)  # 这样可以实现,但是不要用类名调用方法(除了类方法)

方法二

    a1 = A()  # 但是这个功能无需对象参与,非要实例化一个对象,不太合理
    print(a1.func1())

这个时候,无需对象参与的方法,就需要用类方法

    class A:
        name = "Alex"
        count = 1

        @classmethod
        def func1(cls):  # 此方法无需对象参与
            return A.name + str(A.count + 1)


    print(A.func1())
    #结果:Alex2

代码可以改进一下,cls接受的就是类空间

    class A:
        name = "Alex"
        count = 1

        @classmethod
        def func1(cls):  # 此方法无需对象参与
            return cls.name + str(cls.count + 1)


    print(A.func1())

2.对类中的静态变量进行改变的时候,要用到类方法
3.继承中,父类得到子类的类空间

    class A:
        name = "Alex"
        count = 1

        @classmethod
        def func1(cls):  # 此方法无需对象参与
            print(cls)


    class B(A):
        pass


    B.func1()  # 子类通过类名执行父类的方法,并将子类的类名空间传给父类

    # 结果
    # <class '__main__.B'>


面试题:

    class A:
        age = 22

        @classmethod
        def func1(cls):  # 此方法无需对象参与
            # 对B类的所有内容可以进行修改
            print(cls.age)


    class B(A):
        age = 12


    B.func1()  # 子类通过类名执行父类的方法,并将子类的类名空间传给父类

    # 结果
    # 12

思考,如果不用类方法,父类的某个方法如何得到子类空间里的任何东西
其实,在父类里面任意定义一个函数就可以
如下

    class A:
        age = 22

        @classmethod
        def func1(cls):  # 此方法无需对象参与
            # 对B类的所有内容可以进行修改
            print(cls.age)

        def func2(self):
            print(self)  # self就是子类的对象空间,就能得到空间的任意值


    class B(A):
        age = 12


    b1 = B()
    b1.func2()
    # 结果 (B的对象空间)
    # <__main__.B object at 0x00866550>

这样的话,类方法和普通方法的区别就是:
**类方法:传进去的是类空间,在父类里面对子类既能查,也能改**
**普通方法:传进去的对象空间,在父类里面对子类只能访问,查
没有优劣,看需求绝对**



## 静态方法

不需要传对象,和类名空间,只是一个普通的方法定义到函数中

    class A:

        @staticmethod
        def func1():  # 不需要传对象,和类名空间
            print(666)


    A.func1()
    # 结果
    # 666

**静态方法和一个普通函数(不定义在类里面的)的区别**
1.代码块,清晰。将函数分类。把相关的方法,放在一个类里面
2.复用性。可以被继承。



## 总结:

**属性:将方法伪装成一个属性,代码上没有提升,只是更合理**
@property
@属性名.setter
@属性名.deleter
**类方法:**
@classmethod
只能有类名调用(对象调用也行,传给cls参数的也是该对象的所属类)
使用场景:
1,无需对象参与
2.对象中的静态变量进行修改
3.在父类中类方法得到子类的类空间,为所欲为
**静态方法**
@staticmethod
1.代码块,清晰。将函数分类。把相关的方法,放在一个类里面
2.复用性。可以被继承。


python2x 和python3区别
python2x :各种按照自己的习惯给python贡献源码(java的源码的习惯,C#源码的习惯),导致源码混乱,重复性高。(龟叔很生气)
python3x :龟叔重写,源码,优美,清晰,简单。










暂无回复。
需要 登录 后方可回复, 如果你还没有账号请点击这里 注册。