zoukankan      html  css  js  c++  java
  • Py修行路 python基础 (十七)property 静态方法 类方法

    一、property 属性 特性
    (装饰器是可调用对象,被装饰对象也是可调用对象)

      1、在类内函数属性上添加一个@property,就会对函数属性进行伪装。

    import math
    class Circle:
        def __init__(self,radius): #圆的半径radius
            self.radius=radius
    
        @property
        def area(self):
            return math.pi * self.radius**2 #计算面积
    
        @property
        def perimeter(self):
            return 2*math.pi*self.radius #计算周长
    
    c=Circle(10)
    print(c.radius)  #半径
    print(c.area) #面积  可以向访问数据属性一样去访问area,会触发一个函数的执行,动态计算出一个值
    print(c.perimeter) #周长
    
    #执行结果:
    10
    314.1592653589793
    62.83185307179586

      2、这种方法是把函数属性,伪装成数据属性,每次调用执行都是动态计算的结果。使用者直接利用对象名(类名).属性(函数名),调用方法。

    #根据人的身高体重,计算体质
    class People:
        def __init__(self,name,age,height,weight):
            self.name=name
            self.age=age
            self.height=height
            self.weight=weight
    
        @property
        def bodyindex(self): #计算体质
            return self.weight/(self.height**2)
    
    p1=People('cobila',38,1.65,74)  #初始化定义一个对象
    print(p1.bodyindex)   #打印计算的结果
    p1.weight=100        #更改体重
    print(p1.bodyindex)   #再次打印计算的结果
    
    #执行结果:
    27.180899908172638
    36.73094582185492

      好处:1、统一了调用规则,2、封装

    3、被property装饰的属性会优先于对象的属性被使用

    而被propery装饰的属性,如sex,分成三种:
    # 1.property #将函数伪装成属性方法
    # 2.sex.setter #setter更改方法
    # 3.sex.deleter #删除方法

    #被property装饰的属性会优先于对象的属性被使用
    #而被propery装饰的属性,如sex,分成三种:
        # 1.property
        # 2.sex.setter
        # 3.sex.deleter
    class People:
        def __init__(self,name,SEX):
            self.name=name
            # self.__sex=SEX
            self.sex=SEX #self.sex='male' ---> p1.sex='male' #会立马触发 @sex.setter 操作
        @property
        def sex(self):
            return self.__sex  #p1.__sex
    
        @sex.setter
        def sex(self,value):
            # print(self,value)
            if not isinstance(value,str):
                raise TypeError('性别必须是字符串类型')  #主动抛异常
            self.__sex=value  #p1.__sex='male'
        @sex.deleter
        def sex(self):  #不传参数  通常删除方式:del p1.sex
            del self.__sex #del p1.__sex  #删除隐藏属性!
    #优先执行property ---> setter方法 ---> 再执行打印
    p1=People('cobila','male')  #实例化一个对象
    print(p1.sex)  #查看当前的性别
    #
    p1.sex='female'  #更改
    print(p1.sex)  #查看性别
    #执行deleter方法
    print(p1.__dict__) #查看p1的名称空间
    del p1.sex         #删除对象的性别
    print(p1.__dict__) #再次查看对象的名称空间
    
    #执行结果:
    male
    female
    {'name': 'cobila', '_People__sex': 'female'}
    {'name': 'cobila'}

    小补一下:time模块
      time.localtime() #查看当前时间(年 月 日 周 时 分 秒)也可以利用转换成 数字格式。

      计算机内的时间,以秒为单位存在计算机中。
      time.time() #时间戳 计算机的时间格式

    二、封装与扩展性

    注意:只要是写在类中的函数,就是绑定方法,只要是绑定方法,就需要自动传值。

    1、静态方法 staticmethod #解除绑定的方法!!!将类内的函数实例化。

      类普通定义函数属性的时候,属性名会默认添加(self)(类的绑定方法,实例化自动传值),加上@staticmethod,会发现括号内为空(函数不再是类的绑定方法,需要手动传值),不再自动传值。
        通过 staticmethod进行解除绑定到类的方法操作,定义在类内部的函数,并且被@staticmethod修饰过的方法,就是解除绑定的方法。类内定义的函数既不与类绑定,也不与对象绑定。

        此种方法相当于给类扩展了一个功能,将类内的函数实例化,给类或是对象使用。此时类内的函数就是普通的函数,不管是类还是实例化的对象都可以使用,不再属于谁的绑定方法,就是一个函数。
    特性:由于是函数,就需要手动定义位置参数,调用的时候也需要传值。

    import time
    class Date:
        def __init__(self,year,month,day):
            self.year=year
            self.month=month
            self.day=day
        def test(self):
            pass
    
        @staticmethod
        def now(): #用Date.now()的形式去产生实例,该实例用的是当前时间
            t=time.localtime() #获取结构化的时间格式
            obj=Date(t.tm_year,t.tm_mon,t.tm_mday) #新建实例并且返回
            return obj
    
        @staticmethod
        def tomorrow():#用Date.tomorrow()的形式去产生实例,该实例用的是明天的时间
            t=time.localtime(time.time()+86400)
            return Date(t.tm_year,t.tm_mon,t.tm_mday)
    
    #但凡是定义在类的内部,并且没有被任何装饰器修饰过的方法,都是绑定方法:有自动传值功能
    d1=Date(1212,22,22)
    print(d1.test)   #绑定方法
    print(d1.now)    #函数  对象调用
    print(Date.now)  #函数  类调用
    #但凡是定义在类的内部,并且被staticmethod装饰器修饰过的方法,都是解除绑定的方法,实际上就函数:就没有自动传值功能了
    date_now=Date.now()  #定义一个变量使用now()方法
    print(date_now)     #打印类型
    print(date_now.year)  #
    print(date_now.month) #
    print(date_now.day)   #
    d2=Date.tomorrow()    #调用tomorrow
    print(d2.day)         #打印明天
    
    #整体验证
    d_n1=Date.now()
    d_n2=d1.now()
    print(d_n1.year,d_n1.month,d_n1.day)
    print(d_n2.year,d_n2.month,d_n2.day)
    
    #执行结果:
    <bound method Date.test of <__main__.Date object at 0x000000000272BDA0>>
    <function Date.now at 0x000000000272D9D8>
    <function Date.now at 0x000000000272D9D8>
    <__main__.Date object at 0x000000000272BE10>
    2017
    4
    21
    22
    2017 4 21
    2017 4 21

    2、类方法: classmethod #绑定方法 把方法绑定给类,谁来调就是哪个类,而不是再给对象!

      将类内的函数,转换成类方法,函数上装饰@classmethod 会将函数的自动传值参数改成cls。

      classmethod 把一个方法绑定给类:类.绑定到类的方法(),会把类本身当作第一个参数自动传给绑定到类的方法。类和对象都能调用到,但是调用的还是类的绑定方法,传值还是传给类。

    小补一下

      __str__的用法:打印类实例化自动传值的数据。
        def __str__(self): #定义在类内部,必须返回一个字符串类型
          return #什么时候会触发执行:打印由这个类产生的对象才会触发执行。类内调用,必须返回值(字符串),打印结果

    #类的绑定方法,多分析分析__str__的执行过程
    import time
    class Date:
        def __init__(self,year,month,day):
            self.year = year
            self.month = month
            self.day = day
    
        @classmethod
        def now(cls):
            #print(cls)
            t = time.localtime()
            obj = cls(t.tm_year,t.tm_mon,t.tm_day)
            return obj
        @classmethod
        def tomorrow(cls):
            t = time.localtime(time.time()+86400)
            return cls(t.tm_year,t.tm_mon,t.tm_day)
    
    class EuroDate(Date):
        def __str__(self):  #格式化输出
            T = '%s years %s month %s day'%(self.year,self.month,self.day)
            return T
    e1 = EuroDate(2017,4,21)
    print(e1)
    
    #执行结果:
    2017 years 4 month 21 day

      #拿到类的内存地址后,就可以实例化或者引用类的属性了

      只要是写在类中的函数就是绑定方法,只要是绑定方法,类实例化成对象调用的时候,就是把方法绑定给对象。

  • 相关阅读:
    Caused by: org.xml.sax.SAXParseException: The content of elements must consist of well-formed charac
    java反射方法
    错误解决:There is no getter for property named 'id' in class 'java.lang.String'
    java的AOP
    Java预置的注解
    mysql 数据库自动备份
    微信小程序
    关于 IOC和spring基本配置详解
    关于Spring配置的一些东西
    关于Spring的一点东西
  • 原文地址:https://www.cnblogs.com/zh605929205/p/6758896.html
Copyright © 2011-2022 走看看