一,@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)
运行结果: