Python 类的高级特性 类的实例方法和静态方法

一,@property:将类的方法当做属性来使用

      代码示例如下

class PetCat(object):
    """家猫类"""
    def __init__(self,name,age):
        self.name = name
        self.age = age
    @property #加入@property
    def showInfo(self):
        return '我叫{0},我今年{1}岁'.format(self.name,self.age)

if __name__ == '__main__':
    cat_black = PetCat('黑黑猫',3)
    result = cat_black.showInfo #将showInfo方法当做属性使用
    print(result)



返回结果>>>> 我叫黑黑猫,我今年3岁

    说明:把定义好的成员方法  showInfo() 当成属性来使用,当做 @property使用时候 showInfo(self)后 无参数

    类似 当我打印  print(cat_black.name)  输出: 黑黑猫

    @property其他的使用方法:

          例:对猫的年龄进行修改,并对猫的年龄加入判断 保证猫年龄是整数,且在 0-100之间,设置age为私有属性

           代码如下:

class PetCat(object):
    """家猫类"""
    def __init__(self,name,age):
        self.name = name
        self.__age = age #私有变量

    @property #把方法 变成属性使用
    def age(self):
        return self.__age

    @age.setter #当用户给age赋值的时候 就会调用 setter下面的age函数
    def age(self,value):
        """判断传入的年龄是否是整数"""
        if not isinstance(value,int):
            print('年龄只能是整数哦')
            return 0
        """判断年龄是否在 0-100之间"""
        if value < 0 or value > 100:
            print('年龄只能在0-100之间')
            return 0
        self.__age = value

    @property #把不带其他参数的方法 变成属性使用
    def showInfo(self):
        return '我叫{0},我今年{1}岁'.format(self.name,self.age)





if __name__ == '__main__':
    cat_black = PetCat('黑黑猫',3)

    cat_black.age = 10
    result = cat_black.showInfo
    print(result)

说明:

     @方法名.setter :当属性设置为私有属性时,在外部不可以直接修改,因此可以同时使用 @property和  @方法名.setter 可修改私有属性的值

      可以理解为:只有@property表示只读。同时有@property和@*.setter表示可读可写

      setter装饰器必须在property的后面,且两个被修饰的属性(函数)名称必须保持一致,

      isinstance(value, xx): # 判断是否为xx类型

      return 0  执行return 0结束程序,程序不会再继续执行其他语句

  

二,__slots__

            *为指定的类设置一个静态属性列表

            *为属性很少的类节约内存空间

           如下代码,我可以随意的给实例添加属性和方法:我分别给实例加了 color属性 和 eat方法(函数)

class Cat(object):
    def __init__(self,name,age):
        self.name = name
        self.age = age

    @property
    def showInfo(self):
        return '我叫{0},我今年{1}岁'.format(self.name,self.age)
    def __str__(self):
        return '我的对象{0}'.format(self.name)

def eat():
    print('我喜欢吃肉')


if __name__ == '__main__':
    cat_black = Cat('小黑黑',4)
    res = cat_black.showInfo
    print(res)
    #给实例添加新的属性
    cat_black.color = '白色'
    print(cat_black.color)

    # 给实例添加新的方法(函数)
    cat_black.eat = eat
    cat_black.eat()

         运行结果:

              

        如果我们想要限制实例的属性,比如,只允许对实例添加 name和 age属性,就可以用__slots__,在定义class的时候,定义一个特殊的__slots__变量,来达到限制的目的,

           注意:使用__slots__后 不允许给实例添加新的方法和属性

class Cat(object):
    __slots__ = ('name','age')
    def __init__(self,name,age):
        self.name = name
        self.age = age

    @property
    def showInfo(self):
        return '我叫{0},我今年{1}岁'.format(self.name,self.age)
    def __str__(self):
        return '我的对象{0}'.format(self.name)

def eat():
    print('我喜欢吃肉')


if __name__ == '__main__':
    cat_black = Cat('小黑黑',4)
    res = cat_black.showInfo
    print(res)
    #给实例添加新的属性(因代码中设置了__slots__变量,所以会报错)
    cat_black.color = '白色'
    print(cat_black.color)

  运行结果:

       

        *__slots__定义的属性, 方法仅对当前类起作用,对继承的子类是不起作用的

          代码如下:

class Cat(object):
    __slots__ = ('name','age')
    def __init__(self,name,age):
        self.name = name
        self.age = age

    @property
    def showInfo(self):
        return '我叫{0},我今年{1}岁'.format(self.name,self.age)
    def __str__(self):
        return '我的对象{0}'.format(self.name)

class heiCat(Cat):
    pass



if __name__ == '__main__':

    cat_white = heiCat('白白猫',3)
    res = cat_white.showInfo
    print(res)

    #给子类heiCat添加新的属性:
    heiCat.color = '白花猫'
    print(heiCat.color)



运行结果:
>>>>我叫白白猫,我今年3岁
>>>>白花猫

  如果子类中也定义__slots__,那么子类允许定义的属性,方法就是自身的__slots__加上父类的__slots__

  即如果子类没有slots则不会继承父类的slots,如果子类有slots,则在当前限制的属性下还要继承父类的slots

class Cat(object):
    __slots__ = ('name','age')
    def __init__(self,name,age):
        self.name = name
        self.age = age

    @property
    def showInfo(self):
        return '我叫{0},我今年{1}岁'.format(self.name,self.age)
    def __str__(self):
        return '我的对象{0}'.format(self.name)

class heiCat(Cat):
    __slots__ = ("color", )
    pass



def eat():
    print('我喜欢吃肉')


if __name__ == '__main__':
    # cat_black = Cat('小黑黑',4)
    # res = cat_black.showInfo
    # print(res)
    # #给实例添加新的属性(因代码中设置了__slots__变量,所以会报错)
    # cat_black.color = '白色'
    # print(cat_black.color)
    cat_white = heiCat('白白猫',3)
    res = cat_white.showInfo
    print(res)

    #子类定义了__slots__,所以可以输出 白花
    cat_white.color = '白花'
    print(cat_white.color)

    # 子类定义了__slots__ 给子类加入新的属性 会报错
    cat_white.color2 = '白花喵猫'
    print(cat_white.color2)

    运行结果:

   

 三,类的实例方法和静态方法:

     1,实例方法:

            定义:第一个参数必须是实例对象,该参数名一般约定为‘self’,通过它来传递实例的属性和方法(也可以传类的属性和方法)

           调用:只能由实例对象调用

           示例代码:

class myDate(object):
    """实现自己定义的日期类"""
    source = 'mydate'
    def __init__(self,month,day):
        """
        构造方法
        :param month:表示月份
        :param day:表示某一天
        """
        self.month = month
        self.day = day

    def showInfo(self):
        """
         展示日期详情
        :return:
        """
        print('月份:{0},日期:{1}'.format(self.month,self.day))
        #实例方法访问类的属性:
        print('实例方法访问类的属性:{0}'.format(self.source))



if __name__ == '__main__':
    my_date = myDate(9,9)
    #实例方法调用
    my_date.showInfo() 

返回结果:
>>> 月份:9,日期:9
>>>  实例方法访问类的属性:mydate

  2,类方法:             

       定义:使用装饰器@classmethod.第一个参数必须是当前类对象,该参数一般约定为 ‘cls’ ,通过它来传递类的属性和方法(不能传实例的属性和方法

      调用:实例对象和类对象都可以调用。@classmethod因为持有cls参数,即在类方法中可以来调用类的属性,类的方法,实例化对象等;

    注意:当实例属性和类属性重名时,实例属性优先级高于类属性。可以使用类名调用类属性;使用实例调用实例属性。不建议对实例属性和类属性使用相同的名字。

class myDate(object):
    """实现自己定义的日期类"""
    source = 'mydate'
    def __init__(self,month,day):
        """
        构造方法
        :param month:表示月份
        :param day:表示某一天
        """
        self.month = month
        self.day = day

    def showInfo(self):
        """
         展示日期详情
        :return:
        """
        print('月份:{0},日期:{1}'.format(self.month,self.day))
        #实例方法访问类的属性:
        print('实例方法访问类的属性:{0}'.format(self.source))

    @classmethod #表示类方法
    def from_str(cls,dateStr): #cls表示类的引用
        """
         把字符串参数转换成myDate的对象
        :param dateStr:09-09
        :return:对象
        """
        month, day = dateStr.split('-')
        obj = cls(month,day)
        return obj


if __name__ == '__main__':

    #类方法得调用
    new_date = myDate.from_str('09-09')
    new_date.showInfo()

运行结果:
>>> 月份:09,日期:09
>>>实例方法访问类的属性:mydate

 3,静态方法:

     定义:使用装饰器@staticmethod装饰的类中某一个方法(非实例方法),不需要表示自身对象的self和自身类的cls参数,静态方法是类中的函数,不需要实例

    调用:直接类名调用 和 实例化后调用两种都可以调用,静态方法主要是用来存放逻辑性代码,一些逻辑属于类 ,但是和类本身没有交互,即在静态方法中,一般不会涉及到类中的方法和属性的操作。若真的在静态方法中调用这个类的一些属性方法,只能通过直接  类名.属性名/方法名 来调用

    

class myDate(object):
    """实现自己定义的日期类"""
    source = 'mydate'
    def __init__(self,month,day):
        """
        构造方法
        :param month:表示月份
        :param day:表示某一天
        """
        self.month = month
        self.day = day

    def showInfo(self):
        """
         展示日期详情
        :return:
        """
        print('月份:{0},日期:{1}'.format(self.month,self.day))
        #实例方法访问类的属性:
        print('实例方法访问类的属性:{0}'.format(self.source))

    @classmethod #表示类方法
    def from_str(cls,dateStr): #cls表示类的引用
        """
         把字符串参数转换成myDate的对象
        :param dateStr:09-09
        :return:对象
        """
        month, day = dateStr.split('-')
        obj = cls(month,day)
        return obj

    @staticmethod #设置成静态方法
    def validation_month(month):#不需要传递self 和 cls
        """
        静态方法:验证月份是否合法 1-12之间
        :return:是否合法 True 或者 False
        """
        month = int(month)
        return 1 <= month <= 12


if __name__ == '__main__':
    my_date = myDate(9,9)
    #实例方法调用
    my_date.showInfo()

    #类方法得调用
    new_date = myDate.from_str('09-09')
    new_date.showInfo()

    # 静态方法得调用
    res = myDate.validation_month('08')
    print(res)

 运行结果:

   

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值