一、内置类属性(魔法属性)
内置类属性就是魔法属性
魔法属性:属性名的前面和后面都有两个下划线
魔法方法:方法的前面和后面都有两个下划线
声明类
class Person:
'''人类'''
# 类的字段
number=61
def __init__(self,name,age,height):
self.name=name
self.age=age
self.height=height
def run(self):
print('%s在跑步'%(self.name))
@classmethod
def show_number(cls):
print('人类的数量为%d'%(cls.number))
@staticmethod
def destroy():
print('人类在破坏环境')
===================================================
声明对象
p1=Person('张三',28,170)
1,常用内置属性
1.1,name--->类的名字(是个字符串)
类的属性
name=Person.__name__
print(name,type(name),type(Person))
1.2,class属性---获取对象对应的类(是一个类)
对象的属性
# my_class是一个类,之前类能做的事它都能做
my_class=p1.__class__
p2=my_class('小明',20,180)
print(p2.name,my_class.__name__)
1.3.dict属性---将对象和类的属性及其对应的值转换成键值对存到一个字典中
print(Person.__dict__)
print(p1.__dict__)
1.4.doc属性---获取类的说明文档
类的属性
doc=Person.__doc__
print(doc)
1.5.moudle属性---获取类所在的模块对应的名字
print(Person.__module__)
1.6.bases属性---获取当前类的父类
类的属性
print(Person.__bases__)
2、slots 属性约束当前这个类的对象的属性
通过slots中元祖存的元素的值来约束当前这个类的对象的属性。对象中的属性只能比元祖中的元素少,不能多
__slots__ = ('name','age','face')
def __init__(self):
self.name='张三'
self.age=18
self.face=70
p1=Person()
# 一旦在类中给slots赋了值,那么这个类的对象的dict属性就不能使用
print(p1.__dict__)
p1.sex='girl' # AttributeError: 'Person' object has no attribute 'sex'
二、私有化
- python中没有真正的私有化
- python的类中默认的属性和方法都是公开的
class Dog:
number=100
__count=200
def __init__(self):
self.color='黄色'
self.age=3
self.name='大黄'
self.__sex='公狗'
def eat(self):
print('%s在叫'%(self.name))
@classmethod
def shout(cls):
print('count',cls.__count)
print('汪汪汪')
@staticmethod
def function():
print('看家')
dog1=Dog()
print(Dog.number)
print(dog1.name,dog1.age,dog1.color)
dog1.eat()
Dog.function()
Dog.shout()
1,私有化
a,类中的属性和方法都可以通过在属性名和方法名前加两个下划线,来让属性和方法变成私有的
b,私有的属性和方法只能在当前的类中使用
print(Dog.__count)
AttributeError: type object 'Dog' has no attribute '__count'
2,私有化原理
在前面有两个下划线的属性名和方法名之前添加了“_类名”来组止外部直接通过直接访问属性名来使用属性
print(dog1._Dog__sex)--------公狗
print(dog1.__dict__)------
------
{'color': '黄色', 'age': 3, 'name': '大黄', '_Dog__sex': '公狗'}
三、保护属性及getter和setter
1,保护属性:
- 保护类型属性:就是在声明对象属性的时候在属性名前加一个下划线来代表这个属性是受保护的属性。那么以后访问这个属性就不要直接访问,要通过getter来获取这个属性的值,setter来给这个属性赋值
- 如果一个属性已经声明成保护类型的属性,那么我们就需要给这个属性添加getter,也可以添加setter
2,添加getter
添加getter其实就是声明一个没有参数有一个返回值的函数
-
格式:
@property
def 去掉下划线的属性名(self):
函数体
将属性相关的值返回
# 给_price属性添加getter
@property
def price(self):
print('在使用_price属性')
return self._price
-
使用场景
如果想要获取对象的某个属性的值前,想要在干点别的事,就可以给这个属性添加getter
想要获取某个属性被使用的时刻
3,添加setter
添加setter就是声明一个有一个参数但是没有返回值的函数。作用是给属性赋值
-
格式
@去掉下划线的属性名.setter
def 去掉下划线的属性名(self,参数):
函数体
# 想要给一个属性添加setter,必须先给这个属性添加getter
@price.setter
def price(self,price1):
if isinstance(price1,int) or isinstance(price1,float):
self._price=price1
else:
self._price=0
-
使用场景
再给属性赋值前想要在干点别的事情,就使用setter
练习,声明一个员工类,其中有一个是否已婚(bool),在获取值之前,根据存的值返回'已婚/未婚'
class Worker:
def __init__(self,name,age,marital):
self.name=name
self.age=age
self._marital=marital
@property
def marital(self):
if self._marital:
return '已婚'
else:
return '未婚'
四、继承
python中类可以继承,并且支持多继承
程序中的继承:就是让子类直接拥有父类的属性和方法(继承后父类中的内容不会因为被继承而减少)
1,继承的语法
class 类名(父类):
——类的内容
注意:如果声明类的时候没有写继承,那么这个类会自动继承python的基类,object;相当于class 类名(object) 。python中的所有类都是直接或者间接的继承自object
2,能继承那些东西
- 所有的属性和方法都能继承
- slots属性的值不会继承,但是会影响子类对象的dict属性,不能获取到父类的对象属性
私有也会继承
++++++++++++++++++++++++++++++++++++++++++
class Person(object):
# __slots__ = ('name','age')
number=61
def __init__(self,name='张三',age=18):
self.__age=age
self.name=name
# 对象方法
def show_message(self):
print("姓名:%s"%(self.name))
@classmethod
def show_number(cls):
print('人类的数量%d'%(cls.number))
@staticmethod
def complaint():
print('人类殴打小动物')
++++++++++++++++++++++++++++++++++++++++++++++++++
# 声明一个学生类继承人类
class Student(Person):
pass
++++++++++++++++++++++++++++++++++++++++++++++++
print(Student.number)---------------继承了类的字段
stu1=Student()
stu1.name='李四'
print(stu1.name)----------------------继承了对象属性
stu1.show_message()---------------继承了对象方法
Student.show_number()------------继承了类方法
Student.complaint()------------------继承了静态方法
stu1.sex='man'
print(stu1.sex)-------------------------添加对象属性
print(stu1.__dict__)--------------在父类有slots属性限制时,dict属性不能打印出父类的对象属性
五 方法的重写
子类继承父类,拥有父类的属性和方法后,还可以再添加自己的属性和方法
1,添加方法
直接在子类中声明相应的方法
2,添加对象属性
对象的属性是通过继承父类的init方法继承下来的
如果想要在保留父类的对象的同时添加自己的对象属性,需要在子类的init方法中通过super()去调用父类的init方法
3,方法的重写
在子类中重新实现父类的方法,就是重写
方式一:直接覆盖父类的实现
方式二:保留父类的功能再添加功能
4,类中方法的调用过程
先在当前类找,没有去父类中去找,找不到再去父类的父类中找,以此类推直到基类,如果到基类都没有才崩溃
在第一次找到的位置调用
注意:使用super的时候必须是通过super()来代替父类或是父类对象
class Animal:
def __init__(self):
self.age=0
self.sex='雌'
def shout(self):
print('嗷嗷叫')
class Cat(Animal):
food='鱼'
def __init__(self):
# 调用父类的init方法
super().__init__()
self.name='小花'
def shout(self):
# 通过super()调用父类的方法
super().shout()
print('喵喵。。。')
练习,写一个人类,拥有属性name,age,sex.要求去创建时必须给name和age赋值,sex可不赋
再写一个Staff类,继承Person类,要求保留Person中所有属性,添加新的salary属性
要求创建Staff类的对象时,只能给name赋值(必须赋)
class Person:
def __init__(self,age,sex,name='gfx'):
self.name=name
self.age=age
self.sex=sex
class Staff(Person):
def __init__(self,name):
self.name = name
super().__init__(21,'男',self.name)
self.salary=5000
staff1=Staff('fan')
print(staff1.__dict__)
六、运算符的重载
如果希望类的对象支持相应的运算符的操作(例如 + - * /),这个过程就叫运算符的重载
一般情况需要对>或者<进行重载,重载后可以通过sort方法直接对对象的列表的排序
class Student:
def __init__(self,name='',age=0,score=0):
self.name=name
self.age=age
self.score=score
# self:+前面的对象
# other:+后面的对象
# +
def __add__(self, other):
return self.score+other.score
# 重载“>”符号
# 重载“>”“<”可以只重载一个,另外一个对应的功能自动取反
def __gt__(self, other):
return self.score>other.score
# 重写魔法方法__str__用来定制对象的打印样式
def __str__(self):
return 'Student: %s %d %d'%(self.name,self.age,self.score)
stu1=Student('小明',18,90)
stu2=Student('小王',21,80)
print(stu1+stu2)-------------------
print(stu1>stu2)
print(stu1<stu2)
all_students=[stu1,stu2]
all_students.sort()
stu1=Student('小明',18,90)
stu2=Student('小王',21,80)
++++++++++++++++++++++++++++++++++
print(stu1+stu2)
print(stu1>stu2)
print(stu1<stu2)
all_students=[stu1,stu2]
all_students.sort()------------当 重载“>”符号后,可以直接调用sort函数
for x in all_students:
print(x.name,x.age,x.score)
++++++++++++++++++++++++++++++++++
重载的运算符可以被继承
c1=School('小明',18,90)
c2=School('小王',21,84)
print(c1+c2)
print(stu1)
网友评论