类的成员描述符(属性)
- 类的成员描述符是为了在类的成员属性进行相关操作而创造的一种方式
- get : 获取属性的操作
- set : 修改或添加属性的操作
- delete : 删除属性的操作
- 三种方法使用成员描述符
- 使用类实现描述器
- 使用属性修饰符
- 使用property函数
- property(fget,fset,fdel,doc)
- 修饰符都是为了对成员属性进行相应的控制
- 类的方式:适合多个类中的多个属性共用一个描述符
- property: 在当前类中使用,可以控制一个类中的多个属性
- 属性修饰符:在当前类中使用,可控制一个类的一个属性
In [7]:
#属性案例
#当姓名属性需要一至时,例如都需要大写
class Student():
def __init__(self,name,age):
self.name = name
self.age = age
#调用
self.setName(name)
def intro(self):
print('My name is {0},I am {1}'.format(self.name,self.age))
#定义名字大写
def setName(self,name):
self.name = name.upper()
s1 = Student('haha',18)
s1.intro()
My name is HAHA,I am 18
In [27]:
#property案例
#姓名大写,年龄整数
class Person():
'''
这是说明文档
'''
#函数名称可以任意
def fget(self):
return self._name * 2
def fset(self,name):
self._name = name.upper()
def fdel(self):
self._name = "Noname"
name = property(fget,fset,fdel,"对名字进行修改")
p1 = Person()
p1.name = 'haha'
print(p1.name)
HAHAHAHA
类的内置属性
__dict__:以字典的方式显示类的成员组成
__doc__:获取类的文档信息
__name__:获取类的名称,如果在模块中使用,获取模块的名称
__bases__:获取莫各类的所有父类,以元组的方式显示
In [31]:
#类的内置属性
print(Person.__dict__)
print(Person.__doc__)
print(Person.__name__)
print(Person.__bases__)
{'__module__': '__main__', '__doc__': '\n 这是说明文档\n ', 'fget': <function Person.fget at 0x7f683dacec80>, 'fset': <function Person.fset at 0x7f683daceb70>, 'fdel': <function Person.fdel at 0x7f683dace8c8>, 'name': <property object at 0x7f683d20e1d8>, '__dict__': <attribute '__dict__' of 'Person' objects>, '__weakref__': <attribute '__weakref__' of 'Person' objects>} 这是说明文档 Person (<class 'object'>,)
类的常用魔术方法
- 魔术方法就是不需要人为调用的方法,基本是在特定的时刻自动触发
- 特征,方法名被前后两个下划线包裹
- 操作类
- init:构造函数
- new:对象实例化方法,此函数比较特殊,一般不需要使用
- call:对象当函数使用的时候触发
- str:当对象被当做字符串使用时
- repr:返回字符串
- 描述符相关set,get,delete
- 属性操作相关
- getattr:访问一个不存在的属性时触发
- setattr:对成员函数进行设置时触发
- 参数:
- self用来获取当前对象
- 被设置的属性名称,以字符串形式出现
- 需要对属性名称设置的值
- 作用:对属性设置时进行验证或者修改
- 注意:在该方法中不能对属性进行赋值操作,否则死循环
- 参数:
- 运算类相关魔法方法
- gt:进行大于判断时触发的函数
- 参数:
- self
- 第二个参数是第二个对象
- 返回值可以是任意值,推荐返回bool值
In [69]:
#__init__,__call__,__str__举例
class A ():
def __init__(self,name=0):
print('我被调用了')
def __call__(self,name=0):
print('我被调用了啊啊啊')
def __call__(self):
return '啊啊啊'
a =A()
a() #call的使用
我被调用了
Out[69]:
'啊啊啊'
In [39]:
# __getattr__
class A():
name = 'hahaha'
age = 18
def __getattr__(self,name):
print('没有啊没有啊')
print(name)
a = A()
print(a.name)
print(a.addr)#类中没有addr属性
hahaha 没有啊没有啊 addr None
In [44]:
#__setattr__案例
class Person():
def __init__(self):
pass
def __setattr__(self,name,value):
print('设置属性:{0}'.format(name))
#以下语句会导致死循环
#self.name = value
#此种情况,为避免死循环,规定统一调用父类魔法函数
super().__setattr__(name,value)
p = Person()
print(p.__dict__)
p.age =18
{} 设置属性:age
In [47]:
#__gt__案例
class Student():
def __init__(self,name):
self._name = name
def __gt__(self,obj):
print('{0}比{1}大吗?'.format(self,obj))
return self._name>obj._name
stu1 = Student('one')
stu2 = Student('two')
print(stu1>stu2)
<__main__.Student object at 0x7f683d13da58>比<__main__.Student object at 0x7f683d13da20>大吗? False
类和对象的三种方法
- 实例方法
- 需要实例化对象才能使用的方法,使用过程种可能需要截止对象的其他对象的方法完成
- 静态方法
- 不需要实例化,通过类直接访问
- 类方法
- 不需要实例化
- (区别自行百度)
In [82]:
#案例
class Person():
#实例方法
def eat(self):
print(self)
print('eating')
#类方法
#类方法的第一个参数,一般命名为cls,区别于self
@classmethod
def play(cls):
print(cls)
print('playing')
#静态方法
#不需要用第一个参数表示自身或者类
@staticmethod
def say():
print('saying')
p = Person()
#实例方法
p.eat()
#类方法
Person.play()
p.play()
#静态方法
Person.say()
p.say()
<__main__.Person object at 0x7f683d048780> eating <class '__main__.Person'> playing <class '__main__.Person'> playing saying saying