内置类属性
内置类属性就是魔法属性
魔法属性: 属性名前后都有两个下划线
魔法方法: 方法的前后都有两个下划线
![](https://img.haomeiwen.com/i13692213/2dab0c3d6b74605f.jpg)
- 案例
import datetime
class Person:
"""这里是类的说明文档"""
def __init__(self,name,age):
self.name = name
self.age = age
@classmethod
def work(cls):
print('人类,瓦斯塔拉,我们艾欧尼亚人')
@staticmethod
def destroy():
print('无形之刃最为致命')
- __name__
# 1. __name__ 属性 -- 得到类的名字(字符串)
name = Person.__name__
print(name,type(name))
result:
Person <class 'str'>
- __doc__
# 2.__doc__ 属性 --得到类的说明文档
doc = Person.__doc__
print(doc,type(doc))
result:
这里是类的说明文档 <class 'str'>
- __class__
# 3.__class__ 属性 --获取对象对应的类,返回的是一个类型
class2 = lv.__class__
lm = class2('Yasuo',21)
print(class2,type(class2),lm.name,lm)
result:
<class '__main__.Person'> <class 'type'> Yasuo <__main__.Person object at 0x008B6F70>
- __dict__
# 4.__dict__属性 -- 将对象和类的属性及其对应的值转换成键值对存到字典中
dict2 = Person.__dict__
print(dict2)
dict3 = lv.__dict__
print(type(dict3),dict3)
result:
{'__module__': '__main__', '__doc__': '这里是类的说明文档', '__init__': <function Person.__init__ at 0x026B5738>, 'work': <classmethod object at 0x007EC450>, 'destroy': <staticmethod object at 0x02686E30>, '__dict__': <attribute '__dict__' of 'Person' objects>, '__weakref__': <attribute '__weakref__' of 'Person' objects>}
<class 'dict'> {'name': 'Zed', 'age': 20}
- __module__
# 5.__module__属性 -- 获取类所在模块对应的名字
print(Person.__module__)
print(datetime.datetime.__module__)
result:
__main__
datetime
- __bases__
# 6.__bases__属性 --获取父类的名字
print(Person.__bases__)
result:
(<class 'object'>,)
![](https://img.haomeiwen.com/i13692213/ac13a609e85d7ae6.jpg)
slots属性
- 根据
__slots__
中存的值来限制对象的属性,不含的属性不能声明使用或添加 - 一旦在类中给
__slots__
属性赋值,那么在这个类的对象就不能使用__dict__
属性 - 案例
class Person:
__slots__ = ('name','face') #根据__slots__中存的值来限制对象的属性,不含的属性不能声明使用或添加
def __init__(self,name,face):
self.name = name
self.face = face
if __name__ == '__main__':
# 1.一旦在类中给__slots__属性赋值,那么在这个类的对象就不能使用__dict__属性
print(Person.__dict__)
lv = Person('KKK','face')
print(lv.__dict__)#此句会报错
![](https://img.haomeiwen.com/i13692213/554c38ea467805cf.jpg)
属性私有化
python中并没有真正的私有化
python中默认的属性和方法都是公开的
-
私有化
a.类中的属性和方法都可以通过在属性名和方法名前加两个下划线
,让属性和方法变成私有的。
b.私有的属性和方法只能在当前的类中使用 -
私有化原理
在前面有两个下划线的属性名和方法名前添加_类名
来阻止外部通过直接访问属性名来使用属性 -
案例
class Dog:
variety = '秋田'
__count = '私有count'
def __init__(self):
self.color = 'yellow'
self.age = 3
self.name = '大黄狗'
def eat(self):
print('%s都吃屎' % self.name)
@classmethod
def shout(cls):
print(cls.__count)
# cls.__eat()
print('汪汪汪汪~')
@staticmethod
def func():
print('咬人,可疼可疼了')
@staticmethod
def __eat(cls):
print('下划线下划线吃便')
if __name__ == '__main__':
big_yellow = Dog()
Dog.shout() #在类的里面可以使用类的私有属性
# print(Dog.__count)#在类的外面不能直接是私有的属性
# big_yellow.__eat()
print(Dog._Dog__count)
Dog._Dog__eat(Dog)
result:
私有count
汪汪汪汪~
私有count
下划线下划线吃便
![](https://img.haomeiwen.com/i13692213/5cdd6d0224dd3c4c.jpg)
保护类型的getattr和setattr
-
保护类型的属性
a.就是在声明对象属性的时候在属性名前加一个下划线来代表这个属性是受保护的属性。那么以后访问这个属性的时候不要直接访问,要通过getter
获取值和setter
来给属性赋值。
b.如果一个属性已经声明成保护类型的属性,那么我们需要给这个属性添加getter
,也可以添加setter
。 -
添加getter
添加getter
其实就是声明一个没有参数有一个返回值的函数
a.格式@property def 去下划线的属性名(self): 函数体 将属性相关的值返回
b.使用场景
如果想要获取对象的某个属性的值之前,想要对这个属性进行处理再返回就可以使用
获取属性被使用的时刻 -
添加setter
添加setter就是声明一个有一个参数但是没有返回值的函数
a.格式@去下划线的属性名.setter def 去下划线的属性名(self,去下划线的属性名): 函数体
b.使用场景
对受保护的属性进行修改值的时候,通过gett给属性赋值 -
案例
class Car:
def __init__(self):
self.color = 'yellow'
self.type = 'bicycle'
# 保护类型
self._price = 20000
# 给 _price 属性添加getter
@property
def price(self):
return str(self._price/1000)+'K'
#想要给一个属性添加setter,需要先有getter
@price.setter
def price(self,price):
if isinstance(price,int) or isinstance(price,float):
self._price = price
else:
self._price = 0
if __name__ == '__main__':
car =Car()
#添加完getter后就通过getter去获取属性的值
# price就是属性_price的getter
print(car.price)
#通过setter给属性赋值
car.price = 'abc'
print(car.price)
result:
20.0K
0.0K
![](https://img.haomeiwen.com/i13692213/7fb0d6524f943114.jpg)
继承
python中类可以继承,并且支持多继承
程序中的继承: 就是让子类直接拥有父类的属性和方法(继承后父类中的内容不会因为被继承而减少)
- 继承的语法
class 类名(父类):
类的内容
注意: 如果声明类没有写继承的类,那么它会自动继承基类object.
python中所有的类都是直接或间接继承object
- 可继承的项
a.所有属性和方法都能继承
b.__slots__的值不会继承,但是会影响子类对象__dict__属性。(只显示子类的属性)
- 案例
class Person(object):
number2 = 10
__private_msg = 500
__slots__ = ('name','face')
def __init__(self,name='光明',face='nice'):
self.name = name
self.face = face
def show_msg(self):
print('姓名: %s 容貌: %s' % (self.name,self.face))
@classmethod
def show_number(cls):
print('show_number:%d' % cls.number2)
@staticmethod
def show_msg2():
print('No message')
class Student(Person):
pass
if __name__ == '__main__':
# Person类
p = Person()
# print(p.__dict__)
# Student类
stu = Student()
print(Student.number2,stu.name,stu.face)
stu.show_msg()
Student.show_number()
Student.show_msg2()
print(Student._Person__private_msg)
stu.age = 20
print(stu.__dict__)
result:
10 光明 nice
姓名: 光明 容貌: nice
show_number:10
No message
500
{'age': 20}
![](https://img.haomeiwen.com/i13692213/50ac0f0aa47a782e.jpg)
方法的重写
子类继承父类,拥有父类的属性和方法以后,还可以再添加自己的属性和方法
- 添加方法
直接在子类中声明相应的方法 - 添加对象属性
对象的属性是继承父类的init
方法而继承下来的
如果想要早保留父类的对象的同时添加自己的对象属性,需要在子类的init方法中通过super()
去调用父类的init方法。 - 方法的重写
在子类中重新实现父类的方法就是重写
方式1:直接覆盖父类的实现
方士2:保留父类的功能,再添加其他的功能 - 类中方法的调用过程
先在当前这个类中找,没有去父类中找,找不到就去父类的父类中找,找不到就崩溃。注意: 使用super的时候必须通过super()来代替父类或父类对象。 - 案例
class Animal:
def __init__(self):
self.age = 0
self.sex = '雌'
def shout(self):
print('嗷嗷嗷~')
class Cat(Animal):
food = 'fish'
def __init__(self):
super().__init__()
self.name = '阿花'
def shout(self):
#通过super()调用父类的方法,保留父类的功能
super(Cat, self).shout()
print('喵喵喵~')
if __name__ == '__main__':
ani = Animal()
ani.shout()
cat = Cat()
print(cat.__dict__)
cat.shout()
result:
嗷嗷嗷~
{'age': 0, 'sex': '雌', 'name': '阿花'}
嗷嗷嗷~
喵喵喵~
![](https://img.haomeiwen.com/i13692213/7eb4809d9a513459.jpg)
init方法的重写
- 案例
#写一个person类,拥有属性name,age,sex。要求创建Person对象的时候必须给name和age赋值,sex可赋值也可以不赋值。
#再写一个staff类,继承自person类,要求保留person中所有的属性,并添加新的属性salary。
#要求创建staff类的对象的时候,只能给name赋值且必须赋值。
class Person:
def __init__(self,name,age,sex='mole'):
self.name = name
self.age = age
self.sex = sex
class Staff(Person):
def __init__(self,name):
super(Staff, self).__init__(name,10)
self.salary = ''
self.name = name
if __name__ == '__main__':
staff = Staff('王安石')
![](https://img.haomeiwen.com/i13692213/d22b9beaae0c77a0.jpg)
运算符的重载
- 如果希望类的对象支持相应的运算符操作,就必须实现相应的魔法方法。此过程称为运算符重载
- 父类重载了运算符子类也可以使用
- +运算
( __add__()函数)
- >运算
(__gt__()函数)
一般情况需要对>或者<进行重载,重载后可以通过sort方法对包含对象的列表进行排序
![](https://img.haomeiwen.com/i13692213/fbc3fbecfb0b350a.jpg)
- 案例
class Student:
def __init__(self,name,age,sex):
self.name = name
self.age = age
self.sex = sex
# self,other分别为相加的两个对象
def __add__(self, other):
list2 = []
list2.append(self.__dict__)
list2.append(other.__dict__)
return list2
#重载 > 方法
def __gt__(self, other):
return self.age > other.age
#重写魔法方法__str__,用来定制对象的打印形式
def __str__(self):
return '%s %d %s' % (self.name,self.age,self.sex)
if __name__ == '__main__':
stu1 = Student('周一',10,'男')
stu2 = Student('周二',50,'女')
stu3 = Student('周三',25,'人妖')
list2 = [stu1,stu2,stu3]
list2.sort()
for n in list2:
print(n)
print(stu1+stu2)
print(stu1.__add__(stu2))
result:
周一 10 男
周三 25 人妖
周二 50 女
[{'name': '周一', 'age': 10, 'sex': '男'}, {'name': '周二', 'age': 50, 'sex': '女'}]
[{'name': '周一', 'age': 10, 'sex': '男'}, {'name': '周二', 'age': 50, 'sex': '女'}]
网友评论