编程思想
面向过程编程(Procedural programming):根据业务逻辑从上到下写代码,关注于具体怎样实现。
面向函数编程(Function oriented programming):将面向过程编程过程中有重复的代码,封装成一个独立的函数。(函数等价于功能)
面向对象编程(Object Oriented Programming,OOP):不在乎具体实现,只在乎结果。把对象作为程序的基本单元,一个对象包含了数据和操作数据的函数。
类和对象
类是对具有相同特征或者行为的事物的一个统称,是抽象的,不能直接使用。
对象就是类的实例,对象是由类创建出来的一个具体存在的,可以直接使用。
定义类
语法:
class 类名:
类的说明文档
类的内容(属性和方法)
说明:
class-关键字
类名 -自定义
要求:标识符,不能是关键字
规范:大驼峰式命名,并且首字母大写;见名知义;
类的说明文档-用三双引号引起来的说明文字,主要是说清楚类提供了那些属性和方法。
定义对象
语法:
类名()-类名式已经定义好的类的类名
方法
类中的方法三种:对象方法、类方法、静态方法
对象方法
定义: 直接定义在类中的方法
特点: 自带参数self(系统会自动将当前对象传给self)
调用: 用对象调用对象名.对象方法名()
类方法
定义: 定义函数前将加装饰器@classmethod
特点: 自带参数cls(系统会自动将当前类传给cls)
调用: 用类调用类名.类方法名()
静态方法
定义: 定义函数前将加装饰器@staticmethod
特点: 没有默认参数
调用: 用类调用类名.静态方法名()
注意:本质上,对象和类都可调用类中的所有方法,但是不能这样做。
__init__方法
构造方法:函数名和类名一致,用来创建对象的方法就是构造方法。
python中的构造方法,在定义类是就已经定义好了。
__init__方法又叫初始化方法,用来创建对象时,对对象进行初始化的。
魔法方法:以双下划线开始和结尾的方法,不需要手动调用,会自动调用。
创建对象时会自动调用__init__方法,将创建对象时参数传给__init__,用来给属性赋值。
属性
属性:对象属性和类属性
对象属性: 对象属性又称为实例属性,记录对象数据,不同对象的同名实例属性,记录的数据各自独立的,互不干扰。
定义: 定义在__init__函数中的属性
**特点: ** 对象属性的值会因为对象的不同而不同
**调用: ** 对象.对象属性名
类属性:
定义: 直接定义在类中的变量
特点: 类属性的值不会因为对象不同而一样
调用: 类.类属性名
对象属性的增删改查
查
对象.属性-获取对象指定属性的值,属性不存在时会报错。
getattr(对象,属性名)-获取对象指定属性对应的值,但属性不存在时会报错。
getattr(对象,属性名,默认值)-获取对象指定属性的值,属性不存在时不会报错,返回默认值。
增、改
对象.属性=值-当属性不存在就添加属性,当属性存在就修改属性的值。
setattr(对象,属性名,值)-当属性不存在就添加属性,当属性存在就修改属性的值。
删
del 对象.属性-删除指定的对象属性
delattr(对象,属性名)-删除指定的对象属性
注意:对象是可变的,可以对变量和函数的封装
# python中类的对象的属性支持增删改查
class Student:
def __init__(self, name, age=0, gender='男', score=0):
self.name = name
self.age = age
self.gender = gender
self.score = score
def __repr__(self):
return f''
stu1 = Student('小明')
stu2 = Student('小花', gender='女')
# 1.查(获取属性的值)
print(stu1.name)
# print(stu1.name1) # AttributeError: 'Student' object has no attribute 'name1'
print(getattr(stu1, 'name')) # 小明
print(getattr(stu1, 'age')) # 0
# print(getattr(stu1, 'name1')) # AttributeError: 'Student' object has no attribute 'name1'
print(getattr(stu1, 'name', '无名氏')) # 小明
print(getattr(stu1, 'name1', '无名氏')) # 无名氏
# 根据输入的内容获取对象属性的值
# name -> 小明
# age -> 0
# value = input('请选择(name,age,gender,score):')
# print(getattr(stu1, value))
# 2.改、增
# 属性存在是修改
stu1.name = 'xiaoming'
print(stu1)
stu1.height = 180
print(stu1) #
print(stu1.height)
setattr(stu1, 'age', 18)
print(stu1) #
setattr(stu1, 'weight', 80)
print(stu1) #
print(stu2) #
# 3.删
del stu2.age #
print(stu2)
delattr(stu2, 'gender')
print(stu2) #
内置属性
python在定义类的时候系统自动的添加的属性(从基类中继承下来的属性)就是内置属性
类属性
类.__module__ - 获取定义的模块的模块名
类.__name__ - 获取类名
类.__dict__ - 将类转换对象
类.__doc__-类的说明文档
类.__base__ - 获取当前类的父类
类.__bases__-获取当前类的所有父类
对象属性
对象.__class__ - 获取兑现对应的类
对象.__dict__- 将对象转换成字典
对象.__module__ - 获取定义的模块的模块名
Python中支持动态属性,可以直接通过点语法直接给一个对象添加属性,代码更加的灵活。但是在某些情况下,我们可能需要对属性进行控制,此时,就使用__slots__实现。
__slots__ 可以约束当前类的对象能够拥有那些对象属性,使用__slots__ 之后,不能再使用__dict__,__slots__ 会把属性入元组。
class Person(object):
__slots__ = ('name', 'age')
def __init__(self, name, age):
self.name = name
self.age = age
p = Person('张三', 18)
p.name = '李四'
# 对象p只能设置name和age属性,不能再动态添加属性
# p.height = 180 # 报错
访问权限
严格来说,python中所有的属性和方法都是公开的。
在实际开发中,对象的某些属性或者方法可能只希望在对象的内部别使用,而不希望在外部被访问到,这时就可以定义私有属性和私有方法。
定义方法
在定义属性或方法时,在属性名或者方法名前增加两个下划线__,定义的就是私有属性或方法。
class Person:
def __init__(self,name,age):
self.name = name
self.age = age
self.__money = 2000 # 使用 __ 修饰的属性,是私有属性
def __shopping(self, cost):
self.__money -= cost # __money 只能在对象内部使用
print('还剩下%d元'%self.__money)
def test(self):
self.__shopping(200) # __shopping 方法也只能在对象内部使用
p = Person('张三',18)
# print(p.__money) 这里会报错,不能直接访问对象内部的私有属性
p.test()
# p.__shopping() 这里会报错,__shopping 只能在对象内部使用,外部无法访问
getter和setter
getter作用:在获取某个属性值之前想要做别的事情,就给这个属性添加getter
setter作用:在给属性赋值之前想要做别的事情,就给这个属性添加setter
getter
第一步:在需要添加getter的属性名前加_
第二步:定义getter对应的函数(1.需要@property装饰器 2.函数名就是不带_的属性 3.函数需要一个返回值)
第三步:获取属性值的通过:对象.不带_属性名(本质就是调用getter对应的函数,取到属性值就是函数的返回值)
setter
如果想要给属性添加setter必须先给属性添加getter
第一步:添加getter
第二步:定义setter对应的函数(1.需要@getter函数名.setter 的装饰器 2.函数名就是不带_的属性 3.需要一个参数不需要返回值,这个参数就是尝试给属性赋的值)
第三步:给属性赋值:对象.不带_属性名=值(本质就是调用setter对应的函数)
在实际开发中,如果对象的变量使用了__ 来修饰,就说明它是一个私有变量,不建议外部直接使用和修改。如果硬要修改这个属性,可以使用定义get和set方法这种方式来实现。
class Circle(object):
pi = 3.14
def __init__(self, r):
self.r = r
self._area = Circle.pi * self.r ** 2
self._perimeter = Circle.pi * self.r * 2
@property
def area(self):
self._area = Circle.pi * self.r ** 2
return self._area
@area.setter
def area(self, value):
raise ValueError
@property
def perimeter(self):
self._perimeter = Circle.pi * self.r * 2
return self._perimeter
@perimeter.setter
def perimeter(self, value):
raise ValueError
def __repr__(self):
return f'半径:{self.r},周长:{self.area},面积:{self.perimeter}'
c1 = Circle(3)
print(c1)
"""
半径:3,周长:28.26,面积:18.84
"""
c1.r = 4
print(c1)
"""
半径:3,周长:28.26,面积:18.84
"""