• python学习第18天----属性、类方法、静态方法


    1.属性

    引:计算一个人的MBI值

    class People:
        def __init__(self,name,weight,hight):
            self.name = name
            self.__weight = weight
            self.__hight = hight
        def EX(self):
            result = self.__weight/(self.__hight**2)
            print("%s的BMI值为%s"% (self.name,result))
    p1 = People("Tom",60,1.75)
    p1.EX()
    输出:
    Tom的BMI值为19.591836734693878
    View Code

    问题:对于如上程序虽然实现了功能,但是BMI值是一个名词(就应该封装到属性中),但是上述程序是通过一个方法计算出来的,相当于一个动词

    1)属性:将一个方法伪装成一个属性,在代码的级别上没有本质的提升,但是让其看起来更加合理了

    2)使用:在方法前加上@property这个装饰器,修饰方法,那么这个方法在调用时就不需要加括号了

    class People:
        def __init__(self,name,weight,hight):
            self.name = name
            self.__weight = weight
            self.__hight = hight
        @property
        def EX(self):           #伪装成属性
            result = self.__weight/(self.__hight**2)
            print("%s的BMI值为%s"% (self.name,result))
    p1 = People("Tom",60,1.75)
    p1.EX    
    输出:
    Tom的BMI值为19.591836734693878
    View Code

    3)将一个方法伪装后的属性改值

    #如果在类中被@property @方法名.setter装饰器修饰的方法都存在,然后对被伪装的属性改值,那么就会自动执行被@方法名.setter修饰的方法,并且将要改的值传给被@方法名.setter装饰器修饰的方法的self参数后的参数

    class People:
        def __init__(self,name,weight,hight):
            self.name = name
            self.__weight = weight
            self.__hight = hight
        @property
        def EX(self):           #伪装成属性
            result = self.__weight/(self.__hight**2)
            print("%s的BMI值为%s"% (self.name,result))
        @EX.setter
        def EX(self,a1):
            print(a1)
            print("自动被执行。。。")
    p1 = People("Tom",60,1.75)
    p1.EX = 18                       #不需要括号,直接调用
    输出:
    18
    666
    View Code

    注:若要改属性的值,两个装饰器缺一不可

    #例:修改被伪装的属性的值

    class Person:
        def __init__(self,name,age):
            self.name = name
            self.__age = age
    
        @property
        def age(self):
            return self.__age
        @age.setter
        def age(self,a1):
            if type(a1) is int:
                self.__age = a1
            else:
                print("你输入的值有误")
    p1 = Person("阿狸",18)
    print(p1.age )
    p1.age = 20
    print(p1.age)
    输出:
    18
    20
    说明:首先实例化一个对象,传进去阿狸和18,实例化时自动执行__init__方法,执行时封装了一个名字name;p1.age让别然看来调用的就是p1对象的属性,@procerty就是将age方法伪装成一个属性,然后通过p1.age相当于执行age方法,返回__age私有变量值;p1.age = 20是对属性进行改变,只要值一改变就会自动的执行被@age.setter修饰的方法,并且将要改变的值传给方法的第二个参数
    View Code
    4)删除被伪装的属性【方法名.delerter
    class Person:
        def __init__(self,name,age):
            self.name = name
            self.__age = age
    
        @property
        def age(self):
            return self.__age
        @age.setter
        def age(self,a1):
            if type(a1) is int:
                self.__age = a1
            else:
                print("你输入的值有误")
        @age.deleter
        def age(self):
            print("使用del,自动被执行..")
    del self.__age           #删除私有变量
    p1 = Person("阿狸",18)
    print(p1.age )
    del p1.age
    输出:
    18
    使用del,自动被执行..
    View Code

    总结:可理解为一个执行触发一个方法5)使用场景:property用于类似于求BMI这种,看似是一个名词,但是实际需要计算的,都用property装饰

    2.类方法

    #通过对象调用类的普通方法,会将对象地址传给普通方法的参数self

    class A:
        def func(self):     #普通方法
            print(self)
    a1 = A()
    a1.func()   #通过对象调用普通方法
    A.func(a1)  #通过类名调用普通方法
    输出:
    <__main__.A object at 0x0000025F5AB75EB8>
    <__main__.A object at 0x0000025F5AB75EB8>
    View Code

    1)类方法:就是在普通方法前,通过装饰器@classmethod修饰,再通过类名调用的方法,类方法种第一个参数约定俗成为cls,python自动将类名(类空间)传给cls

    class A:
        @classmethod
        def func(cls):   #类方法
            print(cls)
    A.func()
    输出:
    <class '__main__.A'>
    View Code

    #如果是对象调用类方法,cls得到的是类本身

    class A:
        @classmethod
        def func(cls):   #类方法
            print(cls)
    a = A()
    a.func()
    输出:
    <class '__main__.A'>
    View Code

    2)类方法应用场景

    ①类中有些方法是不需要传入对象的,即不要对象的一起东西

    #对于如下程序,完全不需要实例化对象,但是直接用类名调用函数会出错,需要再类名调用函数时传参

    class Person:
        name = "阿狸"
        age = 18
        def func(self):
            return Person.name+str(Person.age)
    print(Person.func(1))
    p = Person()
    print(p.func())
    输出:
    阿狸18
    阿狸18
    View Code

    #通过类方法时,不再需要创建对象

    class Person:
        name = "阿狸"
        age = 18
        @classmethod
        def func(cls):
            return cls.name+str(cls.age)
    print(Person.func())
    输出:
    阿狸18
    View Code

    ②对类中的静态变量进行改变时,要用到类方法

    class Person:
        name = "阿狸"
        age = 18
        @classmethod
        def func(cls):
            return cls.name+str(cls.age)     #就不再通过【类名.变量】的方式去改变静态变量
    print(Person.func())
    输出:
    阿狸18
    View Code
    ③继承中,父类得到子类的类空间(父类可对子类的所以内容进行修改)
    class A:
    
        @classmethod
        def func(cls): #类方法
            print(cls)      #父类中得到了子类的类空间
            print(cls.age)
    class B(A):
        age = 22
        def func_b(self):
            pass
    B.func()          #子类调用方法,先在子类找,子类找不到,去父类找,父类就得到了子类的类空间
    输出:
    <class '__main__.B'>
    22
    View Code
    3.静态方法

    1)通过装饰器@staticmethod修饰的方法,不需要给方法传递任何的参数,即相当于在类中定义了一个普通函数,不需要传递对象、类等参数

    class A:
        @staticmethod
        def func():       #静态方法
            print(666)
    A.func()
    输出:
    666
    View Code

    2)静态方法优点

    ①在整体代码解构来说,使用静态方法(将方法写到类中)比较清晰,是一个代码块

    ②静态方法可提高代码的复用性

    4.python2.xpython3.x的区别

    1python2.x:各种大牛按照自己代码的习惯给python贡献源码(java的源码习惯,C#源码的小习惯),导致源码混乱,重复

    python2.x中的输出是print()  print

    python2.x中的range就是一个列表[1,2,3]

    python2.x中的输入时raw_input(); input()只允许输入数字

    模块、项目等等区别

    2python3.x:龟叔重写,源码优美、清晰、简单,2020python2.x不再更新

    python3.x中的输出是print()

    Python3.x中,range是一个可迭代对象

    python中的输入是input()

    模块、项目等等区别

    3)将一个方法伪装后的属性改值

       如果在类中被@property @方法名.setter装饰器修饰的方法都存在,然后对被伪装的属性改值,那么就会自动执行被@方法名.setter修饰的方法,并且将要改的值传给被@方法名.setter装饰器修饰的方法的self参数后的参数

     
  • 相关阅读:
    Linux c 开发-17 pugixml xml_node Collection和一个数组的值比较示例
    Linux c 开发-16 不需要头文件也可以编译???
    SourceInsight快捷键
    Linux c 开发-16 VsCode下使用CMakeFile编译项目
    java 字符串转Base64
    Linux c 开发-15 Ubuntu子系统中使用串口
    Linux c 开发-14 一例不能直接调试gdb程序的解决办法
    Ubuntu子系统与Windows互相访文件系统
    Linux c 开发-13 Makefile与VisualStudio Linux C环境对应关系
    Linux c 开发-12 创建子进程
  • 原文地址:https://www.cnblogs.com/piaolaipiaoqu/p/13890405.html
Copyright © 2020-2023  润新知