编程思想:面向过程编程;函数式编程;面向对象编程
面向过程编程 -- 算法逻辑
函数式编程 -- 函数
面向对象编程 -- 类和对象
编程思想要逐渐往高级思想:面向对象编程思想转变
1.什么是类;什么是对象
类就是拥有相同属性,相同功能的对象的集合(抽象的)
对象就是类的实例(具体的)
例:
英雄是类 蛮子就是对象;鱼人也是对象
车是类 具体的某一辆车是一个对象
2.类的声明 -- 确定类的属性和功能是什么
1)语法
class 类名:
类的说明文档
类的内容
2)说明
class - 关键字
类名 - 要求:标识符;不能是关键字
规范:a.首字母大写,驼峰式命名
b.见名知义
c.不能使用系统提供的函数名或者类名
类的说明文档 - 要求和函数说明文档一样
类的内容 - 主要包含类的属性和方法(方法就是声明在类中的函数)
class Person:
def eat(self, food):
print(food)
声明对象
1)语法
对象 = 类()
p1 = Person() # p1中存储的就是Person类的对象
p2 = Person() # 同一个类可以创建多个对象
1.对象方法
类中方法分为:对象方法、类方法和静态方法
1)对象方法
a.怎么声明 -- 直接声明(声明前不需要加装饰器)在类中的函数就是对象方法
b.特点 -- 自带self参数;用对象调用对象方法的时候self不用传参,系统会自动将当前对象传给self
self可以做到谁调用就指向谁
c.怎么调用 -- 以'对象.对象方法()'的形式来调用 - 通过对象来调用对象方法
1.构造函数 - 函数名和类名一样,用来创建类的对象的函数
python中声明类的时候,系统会自动为这个类创建一个构造函数,函数的作用是创建对象
构造方法的执行过程:a.在内存中开辟空间创建对象 b.用创建好的对象去调用init方法
c.返回对象在内存中的地址
# __init__方法
声明在类中用来对对象进行初始化的方法:(当对象一创建出来,这个方法就会被自动调用)
注意:创建对象的时候过程方法需不需要传参,需要传几个,看这个类的__init__方法
1.类中的属性
属性就是声明在类中的变量
类中的属性分为:字段和对象属性
1)字段
怎么声明 -- 声明在类的里面函数的外面的变量就是字段
怎么使用 -- 通过类去使用(以'类.字段'的形式使用)
什么时候用 -- 属性值不会因为对象不同而不同,这样的属性就声明成类是字段
2)对象属性!!!!!!!!!!
怎么声明 -- 以'self.属性名=值'的形式声明在init方法中
怎么使用 -- 通过对象去使用
什么时候用 -- 属性的值可能会因为对象不同而不一样,这样的属性就声明成对象属性
class Student:
def __init__(self):
# 这儿的name、age、gender就是对象属性
self.name = 'jack'
self.age = 19
self.gender = 'nan'
self.study_id = '001'
stu1 = Student()
stu1.age = 18
print(stu1.name, stu1.gender, stu1.age)
class Student:
def __init__(self, name, study_id, gender='boy'):
# 这儿的name、age、gender就是对象属性
self.name = name
self.age = 19
self.gender = gender
self.study_id = study_id
stu2 = Student('lucy', '090')
print(stu2.study_id, stu2.age, stu2.gender, stu2.name)
# 声明一个Dog类,拥有属性:名字;年龄;性别和类型
# 要求创建对象的时候名字、品种必须赋值,年龄和性别可以赋值也可以不赋值
# 拥有两个对象方法,一个用来打印信息
# 一个交换的方法:以xxx汪汪汪的格式打印叫唤信息
class Dog:
def __init__(self, name, breed, age=2, gender='boy'):
self.name = name
self.age = age
self.gender = gender
self.breed = breed
def print_message(self):
print(self.name, self.age, self.breed, self.gender)
dog1 = Dog('jack', '牧羊犬')
dog1.print_message()
# python中类的对象的对象属性支持增删改查
class Person:
def __init__(self, name, age, gender):
self.name = name
self.age = age
self.gender = gender
p1 = Person('jack', 18, 'boy')
p2 = Person('lucy', 20, 'girl')
1.查(获取属性的值)
方法一:对象.属性
方法二:getattr(对象,属性名:str)/getattr(对象,属性名:str,默认值)
方法三:对象.getattribute(属性名)
print(p1.name)
print(getattr(p1, 'age'))
print(p1.__getattribute__('gender'))
增/改
方法一:对象.属性 = 值 #属性存在是修改,不存在是添加
方法二:setattr(对象,属性名,值)
p1.name = 'hua'
print(p1.name)
setattr(p1, 'gender', 'boy')
print(p1.gender)
删
方法一:del 对象.属性
方法二:delattr(对象,属性名)
slots魔法
通过给slots字段赋值来约束当前类的对象有哪些对象属性
1.什么是内置类属性
声明类的时候系统自动添加的属性(可能是字段也可能是对象属性)
class Person:
num = 61
def __init__(self,name, gender, age):
self.name = name
self.age = age
self.gender = gender
def eat(self,food):
print('%s在吃%s' % (self.name, food))
定制当前类的对象的打印
1)重新str方法 --方法的返回值就是对应的打印结果(类型必须是字符串)
2)重写repr方法 -- 这个方法的返回值就是对应的打印结果(类型必须是字符串)
p1 = Person('Jack', 'boy', 19)
1__name__
类的字段;类名.name -- 获取类的名字(字符串)
print(type(Person))
print(type(int))
print(Person.name)
2__doc__
类的字段;类.doc -- 获取类的说明文档
3__class__
对象属性;对象.class -- 获取对象对应的类
相当于:(type(对象))
4__dict__ --
对象属性:对象.dict -- 将对象所有的属性和对应的值转换成一个字典中的键值对(一个对象对应一个字典)
类的字典:类.dict -- 将类转换为一个字典,字典中的元素是类中所有的字段和对应的值
'''
print(p1.dict)
print(Person.dict)
5__module__
类的字段:类.module -- 获取当前类是在哪个模块中声明的(返回的是模块的名字)
6__bases__
类的字段:类.bases -- 获取当前类的父类(返回的是一个元组)
当我们需要在获取属性之前做点别的事情就需要给这个属性添加getter
当需要给属性赋值之前做别的事,就需要给这个属性添加setter
给属性添加getter
1.属性命名时前面加'_'
2.在@property装饰器的后面什么一个对象方法
1)将属性去掉下划线作为方法名
2)方法除了self以外不需要其他参数
3)函数的返回值就是获取这个属性的时候得到的值
3.在外面使用属性的时候,通过’对象.不带下划线的属性'去使用
!:获取属性值的时候,就会自动取调用getter对应的函数
给属性添加setter
属性添加setter之前必须先添加getter
1.保证属性名前有'_'
2.在@getter名.setter后面声明对象方法
a.将属性去掉下划线作为方法名
b.需要一个self以外的参数
c.不需要返回值
3.在外部使用属性的时候,通过’对象.不带下划线的属性'去使用
注意:当给属性赋值的时候,实质是调用setter对应的方法
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
p1 = Person('tony', 13)
print(p1.name, p1.age)
练习:写一个矩形类
属性:长、宽、面积、周长
要求从生活的角度看这个矩形
class Rectangle:
def __init__(self, length, wide):
self._length = length
self._wide = wide
self.area = length*wide
self.perimeter = 2*(length+wide)
@property
def length(self):
return self._length
@length.setter
def length(self, value):
if not (isinstance(value, int)) or isinstance(value, float):
raise ValueError
if value < 0:
raise ValueError
self._length = value
@property
def area(self):
self._area = self._length*self._wide
类中的方法:对象方法、类方法和静态方法
1.对象方法
1)怎么声明:
2)怎么调用:
3)特点:
4)什么时候用:如果实现函数的功能需要用到对象属性,就使用对象方法
2.类方法
1)怎么声明:声明在@classmethon后面
2)怎么调用:用类调用'类.类方法()'
3)特点:有自带的参数cls,表示当前类;这个参数在调用的时候不用传参,系统会自动将当前类传给它
cls:谁调用就指向谁,(如果是对象指向的是对象对应的类)
4)什么时候用:如果实现函数的功能不需要对象属性,但需要类的字段,就使用类方法
3.静态方法
1)怎么声明:声明在@staticmethon后面
2)怎么调用:通过类来调用'类.静态方法()'
3)特点:没有默认参数
4)什么时候用:实现函数的功能即不需要类也不需要对象,就使用静态方法
继承
继承就是让子类直接拥有父类的属性和方法
子类 -- 继承者
父类/超类 -- 被继承者
怎么继承
class 类名(父类1,父类2,。。。)
说明文档
类的内容
说明:
() - 固定写法,如果省略相当于(object)
声明类的时候如果没有写父类,默认继承object(object又叫基类)
父类 - 一个类的父类可以有多个,但是一般情况下只有一个(支持多继承)