01-privatization of attributes 属性的私有化
02-False private attribute getter and setter 假的私有属性
03-class fields and method 类字段和类方法
04-static method 静态方法
05-inheritance of class 类的继承
06-class inheritance override 类的继承重写(掌握)
01-privatization of attributes 属性的私有化
属性的访问权限:公开、保护(python中没有)、私有
公开:指的是在类的外部可以直接使用(默认)
公开属性:属性名是普通单词
私有:只能在类的内部直接使用
私有属性:属性名以两个下划线开头'__'(不以两个下划线结束)
class Person:
"""人"""
def __init__(self, name='', age=0):
# name属性是公开的属性
self.name = name
# __age属性是私有的属性
self.__age = age
def show(self):
# 私有属性可以在类的内部去使用
print(self.__age)
p1 = Person('小明')
print(p1.name)
# 私有属性不能在类的外部去使用
# print(p1.age) # value:AttributeError: 'Person' object has no attribute 'age'
p1.show()
02-False private attribute getter and setter 假的私有属性
实际开发中,声明类的属性,很少会使用真正的私有属性和公开属性(前面加两个下划线的)
实际对属性的要求:
1.可以通过 对象.属性 语法方便的来给属性赋值或者拿到它的值(不能是私有的)
2.给属性赋值的时候,需要对赋过来的值进行规范,不能直接就让值赋给属性(不能是直接的公开属性)
满足要求:就是假的私有属性+getter和setter
1.声明属性,属性名前加一个下划线(这个是规范,不是语法:带一个下划线的属性,不要直接使用)
2.通过给属性添加getter和setter来限制赋值和获取值的过程
a.添加getter:-->限制获取属性值的操作
getter的作用:返回属性的值
@property
def 属性名去掉下划线(self):
其他任何操作
return self.带下滑线的属性名
b.setter-->限制添加属性值的操作
setter的作用:修改属性的值
@属性名去掉下滑线.setter
def 属性名去掉下划线(self, 参数):
其他任何操作
self.带下划线的属性名 = 参数
3.在类的外部通过不带下划线的属性去获取属性的值,或者给属性赋值
示例一:
class Person:
def __init__(self, name, age):
# 声明属性的时候,在属性名前加_,是为了告诉别人,这属性不要直接访问,要通过getter或者setter
self._name = name
self._age = age
@property
def name(self):
if len(self._name) == 0:
return '无名氏'
return self._name
# 给_name属性添加setter
@name.setter
def name(self, name1):
# 可以在给属性赋值前做其他操作
if isinstance(name1, str):
self._name = name1
else:
self._name = ''
@property
def age(self):
return self._age
@age.setter
def age(self, age1):
if isinstance(age1, int):
self._age = age1
else:
print('请重新赋值')
p1 = Person('xi_ao_ming', 9)
# print(p1._name) # 是不会报错,但不推荐使用
# p1._name = '路飞'
p1.name = '娜美'
print(p1.name)
print(p1.age)
p1.age = 0
print(p1.age)
getter一般要添加, setter可以不用写
如果要添加setter必须添加getter
示例二:getter 和 setter的使用以及关系
class Cat:
"""猫"""
def __init__(self, name='', color=''):
self._name = name
self._color = color
@property
def name(self):
return self._name
cat1 = Cat('小花', 'yellow')
cat1._name = '喵喵' # 推荐
print(cat1._name) #显示波浪线-->不推荐
getter 与 setter限制类型的使用
练习
class Student:
"""学生"""
def __init__(self, name='', score=0):
self._name = name
self._score = score
# 在getter中限制类型
@property
def name(self):
if isinstance(self._name, str):
return self._name
return 'sdg'
# 在setter中限制类型
@property
def score(self):
return self._score
@score.setter
def score(self, score1):
if isinstance(score1, int) or isinstance(score1, float):
self._score = score1
else:
print('please input number')
s1 = Student()
s1._name = 'st'
print(s1.name)
s1.score = 3.9
print(s1.name,s1.score)
03-class fields and method 类字段和类方法
3.1.类字段就是类属性:通过类去获取
类字段是声明在类里面,函数外面的变量
3.2.类方法:通过类去调用
格式:
@classmethod -->函数修饰符
def 函数名(cls): -->默认参数cls,系统会自动将调用方法的类传给它
语句块
注意:声明成对象方法还是类方法:看实现的功能是否需要对象属性来支持,如果需要,必须声明成对象方法
class Person:
"""
人类
"""
# 这个person_num就是一个类字段
person_num = 60e8
# @classmethod来说明下面的函数是一个类方法 -->函数修饰符
# 所有的类方法都有一个默认参数cls,这个参数不需要传参,系统会自动将调用方法的类传个它
@classmethod
def hurt_earth(cls):
print(cls)
print('human damages the environment ,hurt earth',Person.person_num,cls.person_num)
# 类字段要用类去使用
print(Person.person_num)
# 通过Person类调用类方法
Person.hurt_earth()
print(Person)
# 类字段要用类去使用
print(Person.person_num)
练习:写一个数学类,提供数据的加、减、乘、除的功能
class Math:
@classmethod
def add(cls,*num):
sum1 = 0
for x in num:
sum1 += x
return sum1
@classmethod
def divide(cls, num1, num2):
return num1/num2
re = Math.add(10, 2, 4)
print(re)
04-static method 静态方法
静态函数:在类中声明,由类来调用的方法
示例一:静态方法
class Math:
"""数学类"""
# multiply就是一个静态方法
@staticmethod
def multiply(num1, num2):
return num1*num2
# 静态方法需要使用类来调用
print(Math.multiply(2, 4))
示例二:静态方法和类方法的区别
共同点:都需要用类名去调用
区别:
1.类方法都有一个默认参数cls指向调用方法的类,但静态方法没有
2.类型不一样,静态方法的类型是function,类方法的类型是method
class Download:
"""下载类"""
# 静态方法
@staticmethod
def download_image(image_file):
print('download picture in %s ' % image_file)
# 类方法
@classmethod
def download_movie(cls, movie_file):
print('download movie in %s' % movie_file)
# 类中的普通函数,也是同过类来调用
def down(num):
print('aaa', num)
Download.download_image('aa/123.png')
print(Download.download_image) # <function Download.download_image at 0x0038B8A0>
Download.download_movie('aa/safa.avi')
print(Download.download_movie) #<bound method Download.download_movie of <class '__main__.Download'>>
Download.down(234)
print(Download.down) # <function Download.down at 0x0038B810>
print(Download.__dict__)
05-inheritance of class 类的继承
继承:继承就是让子类去拥有父类的属性和方法
子类:继承者
父类(超类):被继承者
什么时候用继承:
在写一个类的时候,发现这个类中的部分属性和方法另一个类都拥有,
这个时候就不用去声明这些属性和方法,直接从另外一个类中继承下来就可以了
5.1:怎么继承
class 子类(父类):
子类的类容
class Person:
"""人"""
def __init__(self, name='aaa', age=55):
self.name = name
self.age = age
class Student(Person):
pass
stu1 = Student()
print(stu1.name)
5.2:可以继承哪些东西?
1.公开属性可以继承;私有属性不能继承
2.公开的对象方法可以继承;私有的不行
3.类字段可以
4.类的方法和静态方法可以
总结:属性和方法除了私有的都可以继承;slots不能继承
class Animal:
# 1.对象的属性
__slots__ = ('name', '__age')
def __init__(self, name='abc', age=55):
self.name = name
self.__age = age
def run(self):
print(self.__age)
# 2.对象方法
def eat(self):
print('eat food')
# 私有的对象方法,只能在类的内部调用
def __shout(self):
print('shout')
# 3.类字段
count = 100
# 4.类方法
@classmethod
def class_func(cls):
print('class_func')
# 5.静态方法
@staticmethod
def static_func():
print('static_func')
pass
class Dog(Animal):
# def eat_bone(self):
# print('eat bone'. self.__age)
pass
a = Animal()
a.run()
dog1 = Dog()
# dog1.eat_bone()
print(dog1.name)
# print(dog1.age)
print(Dog.count)
Dog.class_func()
Dog.static_func()
dog1.color = 'red'
print(dog1.color)
06-class inheritance override 类的继承重写(掌握)
声明一个类,如果不声明其父类,那么这个类默认继承自object这个类;
object类是python中所有类直接或者间接的父类
6.1示例一:什么是重写
1.重新实现从父类继承下来的方法-->重写
2.super().方法名()
class Animal(object):
def __init__(self, name):
self.name = name
def shout(self):
print('%s: auf!auf!auf!' % self.name)
def be_beat(self):
print(self.name,'is running')
print('auf!auf!auf!when running')
class Dog(Animal):
# 重写父类的shout方法,然后通过Dog对象调用shout执行的是子类的方法
def shout(self):
print('%s: alf!alf!alf!' % self.name)
# 重写父类的be_beat,保留了父类的功能,并且添加新的功能
# super()-->父类
def be_beat(self):
super().be_beat()
print('angry and bite person')
pass
dog1 = Dog('da_huang')
dog1.shout()
dog1.be_beat()
6.2:init方法的继承和重写
重写init方法要注意:
1.如果需要继承父类的对象属性,就需要通过supr().init()
去保留父类的对象属性,然后再添加新的属性;
2.父类的参数必须写在init后的括号里
class Person:
"""人"""
def __init__(self, name='', age=0):
self.name = name
self.age = age
class Student(Person):
"""
重写init方法要注意:
1.如果需要继承父类的对象属性,就需要通过supr().__init__()去保留父类的对象属性,然后再添加新的属性
"""
def __init__(self, name='aas', age=0, study_id = ''):
super().__init__(name, age)
self.study_id = study_id
pass
stu1 = Student()
print(stu1.study_id)
print(stu1.name)
stu2 = Student('ada', 23, '002')
print(stu2.name)
stu3 = Student(study_id= '003')
print(stu3.study_id)
练习:
写一个正方形类,拥有方法:求面积、求周长;拥有属性边长
写一个长方形类,拥有方法:求面积、求周长;拥有属性长和宽
重点:用getter和setter方法将正方形的边长付给引用的父类(长和宽)
class Rectangle:
"""长方形"""
def __init__(self, length=0, width=0):
self.length = length
self.width = width
def area(self):
return self.length*self.width
def circumference(self):
return (self.length + self.width)*2
class Square(Rectangle):
"""
正方形
"""
def __init__(self, length=0, width=0):
super().__init__(length,width)
self._side = 0
@property
def side(self):
return self._side
@side.setter
def side(self, side):
self.length = side
self.width = side
self._side = side
rec1 = Rectangle(3, 5)
print('>>',rec1.area(), rec1.circumference())
squ1 = Square()
squ1.side = 10
print('>>',squ1.area(), squ1.circumference())