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

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

**普通的方法**

    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>

**类方法通过类名调用的方法类方法中第一个参数约定俗成是clspython自动将类名(类空间)传给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 龟叔重写源码优美清晰简单










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