python基础 编程思想
编程思想
面向过程
|
面向对象
|
|
区别
|
事物比较简单,可以用线性思维解决
|
事物比较复杂,使用简单的线性思维无法解决
|
共同点
|
面向过程和面向对象都是解决实际问题的一种思维方式
|
|
二者相辅相成,并不是独立的
解决复杂问题,通过面向对象方式便于我们从宏观上把握事物之间的复杂关系、方便我们分析整个系统,具体到微观操作,仍然使用面向过程方式来处理
|
类与对象
类:多个类似事物组成的群体的统称,能够帮助我们快速理解和判断事物的性质
数据类型:
不同数据类型属于不同的类
使用内置函数查看数据类型
对象:
1,2,3等都是int类之下包含的相似的不同个例,这些个例专业术语称为实例或对象
类
创建类的语法
class 类名:
pass
类定义不能为空,但如果处于某种原因写了无内容的类定义语句,可以使用 pass 语句来避免错误
类的组成
类属性
实例方法
静态方法
类方法
__init__()函数
所有类都有一个名为 __init__() 的函数,它始终在启动类时执行。
使用 __init__() 函数将值赋给对象属性,或者在创建对象时需要执行的其他操作
每次使用类创建新对象时,都会自动调用 __init__() 函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | # # ----------类和对象---------- class Student: # student为类的名称,由一个或多个单词组成,每个单词首字母大写 place = 'XX' # 类属性 # def在类之内定义的称为方法,类之外的称为函数 def __init__( self ,name,age): # name、age为实例属性 self .name = name self .age = age # 实例方法 def info( self ): print ( "my name is " , self .name, 'age' , self .age) # 类方法 @classmethod def cm( cls ): print ( '类方法' ) # 静态方法 @staticmethod def sm(): print ( "静态方法" ) |
self参数
self 参数是对类的当前实例的引用,用于访问属于该类的变量。
它不必被命名为self,可以随意被调用,但它必须是类中任意函数的首个参数
对象
对象的创建
对象的创建又称类的实例化
语法:
实例名 = 类名()
意义:有了实例,就可以调用类中的方法
1 2 3 4 5 | # 创建student类的对象 stu = Student( '张三' , 8 ) print (stu) # 输出student对象的内存地址,16进制 print (stu.eat()) # 对象名.方法名() print (Student.eat(stu)) # 类名.方法(类的对象),与上一行功能相同,都是调用Student中的eat方法 |
修改对象属性
1 2 3 | # 修改对象属性 stu.name = '李四' print (stu.name, stu.age) |
删除对象属性
1 2 3 | # 删除对象属性 del stu.age print (stu.name, stu.age) |
删除对象
使用del关键字删除对象
1 2 3 | # 删除对象 del stu print (stu) |
类属性、类方法、静态对象
类属性:类中方法外的变量称为类属性,被该类的所有对象所共享
类方法:使用@classmethod修饰的方法,使用类名直接访问的方法
静态方法:使用@staticmethod修饰的主法,使用类名直接访问的方法
1 2 3 4 5 6 7 8 9 10 11 12 13 | # 类属性、类方法、静态方法 print (Student.place) stu = Student( 'a' , 4 ) stu1 = Student( 'b' , 3 ) print (stu.place) print (stu1.place) Student.place = 'AA' print (stu.place) print (stu1.place) # 类方法的使用方式 Student.cm() # 静态方法的使用方式 Student.sm() |
动态绑定属性和方法
python是动态语言,在创建对象后,可以动态绑定属性和方法
1 2 3 4 5 6 7 8 9 10 | stu = Student( 'A' , 20 ) stu1 = Student( 'B' , 18 ) # 动态绑定性别属性 stu.sex = '男' # 只适用于绑定的对象 print (stu.name, stu.age, stu.sex) # 动态绑定方法 def show(): print ( "show" ) stu.show = show stu.show() |
面向对象的三大特征
封装
提高程序安全性
将数据和行为包装在类对象中,在方法内部对属性进行操作,在类对象的外部调用方法。这样,无需关心方法内部的具体实现细节,从而隔离了复杂度。
在python中没有专门的修饰符用于属性的私有,如果该属性不希望在类对象外部被访问,前面使用两个下划线‘__’
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | # ----------面向对象的三大特征---------- # 封装 class Tel: def __init__( self , brand): self .brand = brand def start( self ): print ( "开机。" ) tel = Tel( '小米13' ) print (tel.brand) tel.start() class St: def __init__( self , name, age): self .name = name self .__age = age def show( self ): print ( self .name, self .__age) s = St( '张三' , 15 ) s.show() # print(s.name,s.__age) print ( dir (s)) print (s._St__age) # 在类的外部可以通过_St__age进行访问 |
继承
提高代码的复用性
语法结构:
class 子类类名(parent,parent1):
pass
如果一个类没有继承任何类,则默认继承object
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | # 继承 class Person( object ): # person继承了object def __init__( self , name, age): self .name = name self .age = age def info( self ): print ( self .name, self .age) class S(Person): def __init__( self , name, age, stu_no): super ().__init__(name, age) self .stu_no = stu_no class Teacher(Person): def __init__( self , name, age, toy): super ().__init__(name, age) self .toy = toy stu = S( '张三' , 20 , '1001' ) tea = Teacher( '李四' , 40 , 12 ) stu.info() tea.info() print (stu.stu_no, stu.name, stu.age) |
python支持多继承
定义子类时,必须在其构造函数中调用父类的构造函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | # 多继承 class Book( object ): def __init__( self , name, author, kind, price): self .name = name self .author = author self .kind = kind self .price = price def info( self ): print ( self .name, self .author, self .kind, self .price) class Author( object ): def __init__(auth, aname, age, sex): auth.aname = aname auth.age = age auth.sex = sex def ainfo(auth): print (auth.aname, auth.age, auth.sex) class Reader(Book, Author): def __init__( self , name, author, kind, price, aname, age, sex, readername, rage): Book.__init__( self , name, author, kind, price) Author.__init__( self , aname, age, sex) self .readername = readername self .rage = rage rea = Reader( '活着' , '余华' , '文学' , '25.9' , '余华' , 60 , '男' , '张三' , 20 ) print (rea.name, rea.author, rea.kind, rea.price, rea.aname, rea.age, rea.sex, rea.readername, rea.rage) |
方法重写
如果子类堆积成子父类的某个属性或方法不满意,可以在子类中对其进行重新编写
子类重写后的方法中可以通过super().xxx()调用父类中被重写的方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | # 方法重写 class Person( object ): def __init__( self , name, age): self .name = name self .age = age def info( self ): print ( self .name, '\n' , self .age) class Staff(Person): def __init__( self , name, age, salare): super ().__init__(name, age) self .salare = salare def info( self ): super ().info() print ( self .salare) class Student(Person): def __init__( self , name, age): super ().__init__(name, age) def info( self ): print ( "学生名字:" + self .name + ",年龄:" + str ( self .age)) st = Staff( '张三' , 20 , 3000 ) pe = Person( '李四' , 20 ) st.info() pe.info() a = Student( '王五' , 20 ) a.info() |
object类
object类是所有类的父类,因此所有类都有object类的属性和方法
内置函数dir()可以查看指定对象所有属性
object有一个__str__()方法,用于返回一个对于‘对象的描述’,对应于内置函数str()经常用语print()方法,帮我们查看对象的信息,所以我们经常会对__str__()进行重写
1 2 3 4 5 6 7 8 9 | class Student: def __init__( self , name, age): self .name = name self .age = age def __str__( self ): return '名字:{0},今年{1}岁' . format ( self .name, self .age) stu = Student( '张三' , 20 ) print ( dir (stu)) print (stu) |
多态
简单来说,多态就是‘具有多种形态’,它指的是:即便不知道一个变量索引用的对象到底是什么类型,仍然可以通过这个变量调用方法,在运行过程中根据变量所引用对象的类型,动态决定调用哪个对象中的方法
提高程序的可扩展性和可维护性
类的多态特性,还要满足以下 2 个前提条件:
- 继承:多态一定是发生在子类和父类之间;
- 重写:子类重写了父类的方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | # 多态 class Student: def __init__( self , name, age): self .name = name self .age = age def info( self ): print ( '学生:%s,%d' % ( self .name, self .age)) class Teacher: def __init__( self , name, age): self .name = name self .age = age def info( self ): print ( '老师:%s,%d' % ( self .name, self .age)) class Manager: def __init__( self , name, age): self .name = name self .age = age def info( self ): print ( '领导:%s,%d' % ( self .name, self .age)) s = Student( '王五' , 15 ) t = Teacher( '李四' , 35 ) m = Manager( '张三' , 55 ) s.info() t.info() m.info() |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | class whoInfo: def info( self , who): who.info() class Student: def info( self ): print ( '学生' ) class Teacher: def info( self ): print ( '老师' ) class Manager: def info( self ): print ( '领导' ) a = whoInfo() a.info(Student()) a.info(Teacher()) a.info(Manager()) |
静态语言与动态语言关于多态的区别
静态语言实现多态的三个必要条件
继承
方法重写
父类引向子类对象
动态语言的多态崇尚‘鸭子类型’,当看到一只鸟走、跑、游都像鸭子,那这只鸟就可以被称为鸭子。在鸭子类型中,不需要关心对象是什么类型,到底是不是鸭子,只关心对象的行为
特殊方法和特殊属性
方法
|
属性
|
__doc__
|
表示类的描述信息
|
__module__
|
表示当前操作的对象在那个模块
|
__class__
|
表示当前操作的对象的类
|
__init__()
|
构造方法,通过类创建对象时,自动触发执行
|
__del__
|
|
__call__
|
|
__dict__
|
类或对象中的所有成员
|
__str__
|
如果一个类中定义了str方法,那么在打印对象时,默认输出该方法的返回值
|
__getitem__
|
用于索引操作,如字典。表示获取数据、设置数据、删除数据
|
__setitem__
|
|
__delitem__
|
|
__getslice__
|
该方法表示分片操作,如:列表
|
__setslice__
|
|
__delslice__
|
|
__iter__
|
用于迭代器,之所以列表、字典、元组可以进行for循环,因为类型内部定义了__iter_
|
__new__
|
类中有一个属性 __metaclass__,用来表示该类由谁来实例化创建,所以可以为__metaclass__设置一个type类的派生类,从而查看 类 创建的过程。
|
__metaclass__
|
|
__repr__
|
在python解释器环境下,会默认显示对象的repr表示
如果__str__没有被定义,那么就会使用__repr__来代替输出
__str__和__repr__方法的返回值都必须是字符串
|
__format__
|
|
__item__
|
|
__new__
|
__init__是在类实例被创建之后调用的,它完成的是类实例的初始化操作,而 __new__方法正是创建这个类实例的方法
|
__enter__
|
一个对象如果实现了__enter__和___exit__方法,那么这个对象就支持上下文管理协议,即with语句
|
__exit__
|
|
__len__()
|
拥有__len__方法的对象支持len(obj)操作
|
__hash__
|
拥有__hash__方法的对象支持hash(obj)操作
|
__eq__
|
拥有__eq__方法的对象支持相等的比较操作
|
__get__
|
调用一个属性时,触发
|
__set__
|
为一个属性赋值时,触发
|
__delete__
|
采用del删除属性时,触发
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | # # 特殊方法 class Foo: '''描述信息''' def func( self ): pass # __doc__ print (Foo.__doc__) # 显示类描述信息 a = Foo() # __module__ print (a.__module__) __class__ print (a.__class__) class Student: def __init__( self , name, age): self .name = name self .age = age def __str__( self ): return '名字:{0},今年{1}岁' . format ( self .name, self .age) stu = Student( '张三' , 20 ) print (a.name, a.age) # 张三 18 print (a.__dict__) # 实例对象,显示实例对象的属性字典 print (Foo.__dict__) # 类对象,显示属性对象的方法的字典 print (Foo.__bases__) # 输出Foo类的父类元组 print (Foo.__base__) # 输出Foo类的第一个父类 print (Foo.__mro__) # 类的层次结构 print (Foo.__subclasses__()) # 子类的列表 a = 20 b = 100 c = a + b d = a.__add__(b) print (c, d) class Student: def __init__( self ,name): self .name = name def __add__( self , other): # 实现了两个对象的加法运算,此方法为特殊方法 return self .name + other.name def __len__( self ): return len ( self .name) stu1 = Student( '张三' ) stu2 = Student( '李四' ) stu = stu1.__add__(stu2) print (stu) stu = stu1 + stu2 print (stu) print ( len (stu)) print (stu.__len__()) print (stu1.__len__()) |
__new__()和__init__()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | class Person: def __init__( self , name, age): print ( "__init__被调用了,self的id值为:{0}" . format ( id ( self ))) # 1963885026752 self .name = name self .age = age def __new__( cls , * args, * * kwargs): print ( '当前cls的id为:{0}' . format ( id ( cls ))) # 1963912247344 obj = super ().__new__( cls ) print ( "创建的对象的id为:{0}" . format ( id (obj))) # 1963885026752 return obj print ( 'object类对象的id为:{0}' . format ( id ( object ))) # 140707825368576 print ( 'Person类对象的id为:{0}' . format ( id (Person))) # 1963912247344 p1 = Person( 'zhangsan' , 20 ) print ( "id:{0}" . format ( id (p1))) # 1963885026752 |
类的赋值与浅拷贝、深拷贝
变量的赋值操作
只是形成两个变量,实际上还是指向同一个对象
1 2 3 4 5 6 7 8 9 10 11 12 | # # 类的赋值与浅拷贝、深拷贝 class Cpu: pass class Disk: pass class Computer: def __init__( self , cpu, disk): self .cpu = cpu self .disk = disk # 赋值 cpu1 = Cpu() cpu2 = cpu1 |
浅拷贝
python拷贝一般都是浅拷贝,拷贝时对象包含的子对象内容不拷贝,因此,源对象与拷贝对象会引用同一个子对象
1 2 3 4 5 6 7 8 | # 浅拷贝,相当于一个人的大小名,都指你,你的头发、鼻子都是同一个东西 disk = Disk() computer = Computer(cpu1, disk) import copy computer2 = copy.copy(computer) print (computer, computer.cpu, computer.disk) print (computer2, computer2.cpu, computer2.disk) |
深拷贝
使用copy模块的deepcopy函数,递归拷贝对象中包含的子对象,源对象和拷贝对象所有的子对象也不相同
1 2 3 4 | # 深拷贝,相当于克隆,内容一样,但你是你,他是他,你的东西是你自己的 computer3 = copy.deepcopy(computer) print (computer, computer.cpu, computer.disk) print (computer3, computer3.cpu, computer3.disk) |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报