python
python是一种用途广泛、解释性、面向对象的程序设计语言
我还记得那天
“人生如逆旅,我亦是行人”
展开
-
78 面向对象程序设计精彩案例——自定义栈
设计自定义栈类,模拟入栈、出栈、判断栈是否为空、判断栈是否已满以及改变栈大小的操作。原创 2024-08-09 19:19:52 · 257 阅读 · 0 评论 -
77 特殊方法与运算符重载
在 Python 中,除了构造方法和析构方法之外,还有大量的特殊方法支持更多的功能。例如,运算符重载就是通过在类中重写特殊方法实现的。在自定义类时如果重写了某个特殊方法即可支持对应的运算符或内置函数,具体实现什么工作则完全可以由程序员根据实际需要来定义。如果用户没有设计构造方法,Python 会提供一个默认的构造方法用来进行必要的初始化工作。如果用户没有编写析构方法,Python 将提供一个默认的析构方法进行必要的清理工作。Python 类有大量的特殊方法,其中比较常见的是构造方法和析构方法。原创 2024-08-09 18:32:40 · 198 阅读 · 0 评论 -
76 多态
Python 大多数运算符可以作用于不同类型的操作数,并且对于不同类型的操作数往往有不同的表现,这本身就是多态,是通过特殊方法与运算符重载实现的。派生类继承了基类的行为和属性之后,还会增加某些特定的行为和属性,同时还可能会对继承来的某些行为进行一定的改变,这都是多态的表现形式。原创 2024-08-09 18:11:19 · 151 阅读 · 0 评论 -
75 继承
在继承关系中,已有的、设计好的类称为父类或基类,新设计的类称为子类或派生类。派生类可以继承父类的公有成员,但是不能继承其私有成员。如果需要在派生类中调用基类的方法,可以使用内置函数。Python 支持多继承,如果父类中有相同的方法名,而在子类中使用时没有指定父类名,则 Python 解释器将从左向右按顺序进行搜索,使用第一个匹配的成员。设计一个新类时,如果可以继承一个已有的设计良好的类然后进行二次开发,可以大幅度减少开发工作量,并且可以很大程度地保证质量。的方式来实现这一目的。原创 2024-08-09 17:50:53 · 360 阅读 · 0 评论 -
74 类与对象的动态性、混入机制
这在大型项目开开发中会非常方便和实用。例如,系统中的所有用户分类非常复杂,不同用户组具有不同的行为和权限,并且可能会经常改变。这时可以独立地定义一些行为,然后根据需要来为不同的用户设置相应的行为能力。例如,可以设计一些动作,然后根据需要把这些动作附加到相应的角色上。,这也是 Python 动态类型的一种重要体现。在 Python 中可以。原创 2024-08-09 16:59:58 · 271 阅读 · 0 评论 -
73 属性
① 公开的数据成员可以在外部随意访问和修改,很难保证用户进行修改时提供新数据的合法性,数据很容易被破坏,也不符合类的封装性要求。解决这一问题的常用方法是定义私有数据成员,然后设计公开的成员方法来提供对私有数据成员的读取和修改操作,修改私有数据成员之前可以对值进行合法性检查,提高了程序的健壮性,保证了数据的完整性。③ 如果设置属性为只读,则无法修改其值,也无法为对象增加与属性同名的新成员,当然也无法删除对象属性。原创 2024-08-08 19:40:36 · 338 阅读 · 0 评论 -
72 成员方法、类方法、静态方法、抽象方法
每个对象都有自己的公有方法和私有方法,在这两类方法中都可以访问属于类和对象的成员。公有方法通过对象名直接调用,私有方法不能通过对象名调用,只能在其他实例方法中通过前缀 self 进行调用或在外部通过特殊的形式来调用。如果在外部通过类名调用属于对象的公有方法,需要显示为该方法的 self 参数传递一个对象名,用来明确指定访问哪个对象的成员。① 公有方法、私有方法和抽象方法一般是指属于对象的实例方法,私有方法的的名字以两个或更多个下画线开始,而抽象方法一般定义在抽象类中并且要求派生类必须重新实现。原创 2024-08-08 18:07:56 · 448 阅读 · 0 评论 -
71 为对象定义类
数据域也被称为实例变量,因为每个对象(实例)的数据域中都有一个特定值。方法也被称为实例方法,因为方法被一个对象(实例)调用来完成对象上的动作。③ 对象是类的一个实例,可以创建一个类的多个对象。例如,可以使用 self.x 访问实例变量 x,而使用语法 self.m1() 来调用类的对象 self 的实例方法 m1。定义的每个方法的第一个参数就是 self,这个参数被用在方法的实现中,但不是用在方法被调用的时候。可以使用圆点运算符(.)访问对象的数据域并调用它的方法,它也被称为对象成员访问运算符。原创 2024-08-08 16:17:43 · 428 阅读 · 0 评论 -
70 数据成员
中定义,当然也可以在其他成员方法中定义,在定义和实例方法中访问数据成员时以 self 作为前缀,同一个类的不同对象(实例)的数据成员互不影响。③ 在主程序中或类的外部,对象数据成员属于实例(对象),只能通过对象名访问;② 属于类的数据成员是该类所有对象共享的,不属于任何一个对象,在定义类时这类数据一般不在任何一个成员方法的定义中。利用类数据成员的共享性,可以实时获得该类的对象数量,并且可以控制该类创建的对象最大数量。数据成员可以大致分为两类:属于对象的数据成员和属于类的数据成员。原创 2024-08-07 18:28:15 · 192 阅读 · 0 评论 -
69 私有成员与公有成员
从形式上看,在定义类的成员时,如果成员名以两个(或更多)下画线开头但是不以两个(或多个)下画线结束则表示是私有成员,否则就不是私有成员。私有成员在类的外部不能直接访问,一般是在类的内部进行访问和操作,或者在类的外部通过调用对象的公有成员来访问,而公有成员是可以公开使用的,既可以在类的内部进行访问,也可以在外部程序中使用。在模块中使用一个或多个下画线开头的成员不能用。:以两个或更多下画线开头但不以两个或更多下画线结束,表示私有成员,一般只有类对象自己能访问,子类对象也不能访问该成员,但在对象外部可以通过。原创 2024-08-07 17:49:14 · 244 阅读 · 0 评论 -
68 类的定义与使用
Python 使用 class 关键字来定义类,class 关键字之后是一个空格,接下来是类的名字,如果派生自其他基类则需要把所有基类放到一对括号中并使用逗号分隔,然后是一个冒号,最后换行并定义类的内部实现。类名的首字母一般要大写,也可以按照自己的习惯定义类名,但一般推荐参考惯例来命名,并在整个系统的设计和实现中保持风格一致,这一点对于团队合作非常重要。在 Python 中,可以使用内置函数 isinstance() 来测试一个对象是否为某个类的实例,或者使用内置函数 type() 查看对象类型。原创 2024-08-07 16:59:38 · 321 阅读 · 0 评论 -
67 面向对象程序设计
面向对象程序设计(Object Oriented Programming, OOP)的思想主要针对大型软件设计提出的,使得软件设计更加灵活,能够很好地支持代码复用和设计复用,代码具有更好的可读性和可扩展性,大幅度降低了软件开发的难度。面向对象程序设计的一个关键性观念是将数据以及对数据的操作封装在一起,组成一个相互依存、不可分割的整体(对象),不同对象之间通过消息机制来通信或同步。对于相同类型的对象(instance)进行分类、抽象后,得出共同的特征而形成了类(class),原创 2024-08-07 16:31:21 · 291 阅读 · 0 评论 -
66 函数精彩案例
处理规则为:将列表 s 中下标 k (不包括 k)之前的元素逆序,下标 k (包括 k)之后的元素逆序,然后将整个列表 s 中的所有元素逆序。1 编写函数,接收任意多个实数,返回一个元组,其中第一个元素为所有参数的平均值,其他元素为所有参数中大于平均值的实数。5 编写函数,接收两个正整数作为参数,返回一个元组,其中第一个元素为最大公约数,第二个元素为最小公倍数。2 编写函数,接收字符串参数,返回一个元组,其中第一个元素为大写字母个数,第二个元素为小写字母个数。7 编写函数,模拟二分查找。原创 2024-08-07 16:12:45 · 308 阅读 · 0 评论 -
65 生成器函数设计要点
Python 标准库 itertools 提供了一个 count(start, step) 函数,用来连续不断地生成无穷个数,这些数中的第一个数是 start (默认为0),相邻两个数的差是step (默认为1)。包含 yield 语句的函数可以用来创建生成器对象,这样的函数也称为生成器函数。yield 语句与 return 语句的作用相似,都是用来从函数中返回值。return 语句一旦执行会立刻结束函数的运行,而。原创 2024-08-06 23:25:25 · 162 阅读 · 0 评论 -
64 lambda 表达式
虽然使用 lambda 表达式可以很方便灵活地定义一些小函数,但是,如果仅仅是需要一个简单的运算,那么应该尽量使用标准库 operator 中提供的函数,避免自己定义 lambda 表达式,operator 中的函数执行效率更高一些。lambda 表达式只可以包含一个表达式,不允许包含其他复杂的语句,但在表达式中可以调用其他函数,该表达式的计算结果相当于函数的返回值。lambda 表达式常用来声明匿名函数,即没有函数名字的临时使用的小函数,常用在临时需要一个类似于函数的功能但又不想定义函数的场合。原创 2024-08-06 20:39:41 · 232 阅读 · 0 评论 -
63 变量的作用域
在函数外部和函数内部定义的变量,其作用域是不同的,函数内部定义的变量一般为局部变量,在函数外部定义的变量为全局变量。不管是局部变量还是全局变量,其作用域都是从定义的位置开始的,在此之前无法访问。如果在函数内部修改一个定义在函数外的变量值,必须使用 global 明确声明,否则会自动创建新的局部变量。如果局部变量与全局变量具有相同的名字,那么该局部变量会在自己的作用域内暂时隐藏同名的全局变量。,当函数运行结束以后,在其内部定义的所有局部变量将被自动删除而不可访问。变量起作用的代码范围称为变量的作用域,原创 2024-08-06 19:42:34 · 345 阅读 · 0 评论 -
62 函数参数——传递参数时的序列解包
③ 如果一个函数需要以多种形式来接收参数,定义时一般把位置参数放在最前面,然后是默认值参数,接下来是一个星号的可变长度参数,最后是两个星号的可变长度参数;调用函数时如果对实参使用一个星号 * 进行序列解包,那么这些解包后的实参将会被当作普通位置参数对待,并且会在关键参数和使用两个星号 ** 进行序列解包的参数之前进行处理。,Python 解释器将会自动进行解包,然后把序列中的值分别传递给多个单变量形参。与可变长度的参数相反,这里的序列解包是指实参,同样也有 * 和 ** 两种形式。对于这种形式的序列解包,原创 2024-08-06 18:49:45 · 542 阅读 · 0 评论 -
61 函数参数——可变长度参数
Python 定义函数时可以同时使用位置参数、默认值参数、关键参数和可变长度参数,但是除非真的很必要,否则不要这样做,因为这样会使得代码非常混乱而严重降低可读性,并导致程序查错非常困难。另外,一般而言,如果一个函数可以接收很多不同类型的参数,很可能是函数设计得不好。可变长度参数在定义函数时主要有两种形式:*parameter 和 **parameter,前者主要用来接收任意多个实参并将其放在一个元组中,后者接收类似于关键参数一样显示赋值形式的多个实参并将其放入字典中。原创 2024-08-06 16:24:34 · 243 阅读 · 0 评论 -
60 函数参数——关键参数
明确指定哪个值传递给哪个参数,实参顺序可以和形参顺序不一致,但不影响参数值的传递结果,避免了用户需要牢记参数位置和顺序的麻烦,使得函数的调用和参数传递更加灵活方便。关键参数主要指调用函数时的参数传递方式,与函数定义无关。原创 2024-08-06 16:00:47 · 262 阅读 · 0 评论 -
59 函数参数——默认值参数
在调用带有默认值参数的函数时,可以不用为设置了默认值的形参进行传递,此时函数将会直接使用函数定义时设置的默认值,当然也可以通过显式赋值来替换其默认值。① 可以使用 “函数名. _ _ default _ _ ” 随时查看函数所有默认值参数的当前值,其返回值为一个元组,其中的元素依次表示每个默认值参数的当前值。③ 如果在定义函数时某个参数的默认值为另一个变量值,那么参数的默认值只依赖于函数定义时该变量的值,或者说。在定义函数时,Python 支持默认值参数,在定义函数时可以为形参设置默认值。原创 2024-08-06 15:48:19 · 644 阅读 · 0 评论 -
58 函数参数——位置参数
位置参数是比较常用的形式,调用函数时实参和形参的顺序必须严格一致,并且实参和形参的数量必须相同。原创 2024-08-06 14:44:16 · 315 阅读 · 0 评论 -
57 函数参数
函数定义时括号内是使用逗号分隔开的形参列表,函数可以有多个参数,也可以没有参数,但定义和调用时一对括号必须有,表示这是一个函数并且不接收参数。Python 采用的是基于值的自动内存管理模式,变量并不直接存储值,而是存储值的引用。从这个角度来讲,在 Python 中调用函数时,,解释器会根据实参的类型自动推断形参类型,在一定程度上类似于函数重载和泛型函数的功能。在函数内部修改了形参的值,但是当函数运行结束以后,实参的值并没有被修改。原创 2024-08-06 14:37:12 · 318 阅读 · 0 评论 -
56 函数递归调用
函数递归通常用来把一个大型的复杂问题层层转化为一个与原来问题本质相同但规模很小、很容易解决或描述的问题,只需要很少的代码就可以描述解决问题过程中需要的大量重复计算。② 调用一个函数时会为该函数分配一个栈帧,用来存放普通参数和函数内部局部变量的值,这个栈帧会在函数调用结束后自动释放。③ 在函数递归调用的情况中,一个函数执行尚未结束就又调用了自己,原来的栈帧还没释放又分配了新栈帧,会占用大量的栈空间。① 每次调用函数必须记住离开的位置才能保证函数运行结束以后回到正确的位置,这个过程称为。,这需要一定的栈空间。原创 2024-08-05 20:18:57 · 268 阅读 · 0 评论 -
55 函数嵌套定义、可调用对象与修饰器
函数属于 Python 可调用对象之一,由于构造方法的存在,类也是可调用的。像 list()、tuple()、dict()、set() 这样的工厂函数实际上都是调用了类的构造方法。另外,包含任何 _ _ call _ _ () 方法的类的对象也是可调用的。静态方法、类方法、属性等也都是通过修饰器实现的,Python 中还有很多这样的用法。Python 允许函数的嵌套定义,在函数内部可以再定义另外一个函数。修饰器是函数嵌套定义的另一个重要应用。原创 2024-08-05 19:14:49 · 344 阅读 · 0 评论 -
54 函数基本语法
在 python 中使用 def 关键字来定义函数,然后是一个空格和函数名称,接下来是一对括号,在括号内是形式参数列表,如果有多个参数则使用逗号分隔开,括号之后是一个冒号和换行,最后是注释和函数体代码。在 Python 中,定义函数时也不需要声明函数的返回值类型,而是使用 return 语句结束函数执行的同时返回任意类型的值,无论 return 语句出现在函数的什么位置,一旦得到执行将直接结束函数的执行。① 函数形参不需要声明其类型,也不需要指定函数的返回值类型。③ 括号后面的冒号必不可少。原创 2024-08-05 17:30:35 · 272 阅读 · 0 评论 -
53 程序控制结构精彩案例
1 输入若干成绩,求所有成绩的平均分。每输入一个成绩后询问是否继续输入下一个成绩,回答 yes 就继续输入下一个成绩,回答 no 就停止输入成绩。3 编写代码,输出由 * 号组成的菱形图案,并且可以灵活控制图案的大小。2 编写程序,判断今天是几年的第几天。原创 2024-08-05 17:05:02 · 208 阅读 · 0 评论 -
52 break 与 continue 语句
过多的 break 和 continue 语句会降低程序的可读性,除非 break 或 continue 语句可以让代码简单或更清晰,否则不要轻易使用。break 与 continue 语句在 while 循环和 for 循环中都可以使用,并且一般常与选择结构或异常处理结构结合使用。② continue 语句的作用是提前结束本次循环,忽略 continue 之后的所有语句,提前进入下一次循环。① 一旦 break 语句被执行,将使得 break 语句所属层次的循环提前结束。原创 2024-08-04 18:54:12 · 266 阅读 · 0 评论 -
51 for 循环与 while 循环
Python 主要有 for 循环和 while 循环两种形式的循环结构,多个循环可以嵌套使用,并且还经常和选择结构嵌套使用来实现复杂的业务逻辑。时则执行 else 结构中的语句,如果循环是因为执行了 break 语句而导致循环提前结束则不会执行 else 中的语句。for 循环一般用于循环次数可以提前确定的情况,尤其适用于枚举或遍历序列或迭代对象中元素的场合。while 循环一般用于循环次数难以提前确定的情况,当然也可以用于循环次数确定的情况。原创 2024-08-04 18:22:09 · 224 阅读 · 0 评论 -
50 选择结构
常见的选择结构有单分支选择结构、双分支选择结构、多分支选择结构及嵌套的分支结构,也可以构造跳转表来实现类似的逻辑。循环结构和异常处理结构中也可以实现带有 else 子句,可以看作特殊形式的选择结构。Python 提供了一个三元运算符,并且在三元运算符构成的表达式中还可以嵌套三元运算符,可以实现与选择结构相似的效果。所有的 Python 合法表达式都可以作为条件表达式,包括含有函数调用的表达式。虽然三元运算符可以嵌套使用,可以实现复杂的多分支选择结构的效果,但这样的代码可读性非常差,不建议使用。原创 2024-08-03 23:53:53 · 148 阅读 · 0 评论 -
49 序列解包的多种形式和用法
对字典使用时,默认是对字典的 “键” 进行操作,如果对 “键:值” 对进行操作应使用字典的 items() 方法说明,如果需要对字典 “值” 进行操作应使用字典的 values() 方法明确指定。序列解包(Sequence Unpacking)是 Python 中非常重要和常用的一个功能,可以使用非常简洁的形式完成复杂的功能,提高了代码的可读性,减少了程序员的代码输入量。序列解包的逆运算,与函数的可变参数一样,用来收集等号右侧的多个值。使用序列解包可以很方便地同时遍历多个序列。原创 2024-08-03 19:43:01 · 291 阅读 · 0 评论 -
48 集合应用案例
2 假设已有若干用户名字及其喜欢的电影清单,现有某用户,已看过并喜欢一些电影,现在想找个新电影看,又不知道看什么好。根据已有数据,查找与该用户爱好最相似的用户,也就是看过并喜欢的电影与该用户最接近的用户,然后从那个用户喜欢的电影中选取一个当前用户还没看过的电影,然后推荐。编写代码时除了要准确地实现功能之外,还要考虑代码的优化,尽量找到一种更快、更好的方法实现预定功能。对于成员测试运算符 in,列表地效率远远不如字典和集合,并且随着序列的变长,列表的查找速度越来越慢,而字典和集合基本不受影响。原创 2024-08-03 18:46:56 · 307 阅读 · 0 评论 -
47 集合操作与运算
集合对象的 pop() 方法随机删除并返回集合中的一个元素,如果集合为空则抛出异常;remove() 方法删除集合中的元素,如果指定元素不存在则抛出异常;discard() 方法从集合中删除一个特定元素,如果元素不在集合中则忽略该操作;内置函数 len()、max()、min()、sum()、sorted()、map()、filter()、enumerate()等也适用于集合。update() 方法合并另外一个集合中的元素到当前集合中,并自动去除重复元素。,而不是比较集合中元素的大小关系。原创 2024-08-03 16:54:32 · 398 阅读 · 0 评论 -
46 集合对象的创建与删除
② 可以使用 set() 函数将列表、元组、字符串、range 对象等其他可迭代对象转换为集合,如果原来的数据中存在重复元素,则在转换为集合的时候只保留一个;Python 提供了一个内置函数 hash() 来计算对象的哈希值,凡是无法计算哈希值(调用内置函数 hash() 时抛出异常)的对象都不能作为集合的元素,也不能作为字典对象的 “键”。集合(set)属于 Python 无序可变序列,使用一对大括号作为定界符,元素之间使用逗号分隔,同一个集合内的每个元素都是唯一的,原创 2024-08-02 20:08:36 · 273 阅读 · 0 评论 -
45 标准库 collections 中与字典有关的类
主要介绍 collections 中 OrderedDict 类、defaultdict 类和 Counter类。对于频次统计问题,使用 collections 模块的 Counter 类可以更加快速地实现这个功能,并且能够提供更多的功能,如查找出现次数最多的元素。Python 内置字典 dict 是无序的,如果需要一个可以记住元素插入顺序的字典,则可以使用 collections.OrderedDict。字母出现频次统计问题,可以使用 collections 模块的 defaultdict 类来实现。原创 2024-08-01 23:50:43 · 254 阅读 · 0 评论 -
44 字典元素的添加、修改、删除
为字典元素赋值时,有两种含义:① 若该 “键” 存在,则表示修改该 “键” 对应的值;② 若该 “键” 不存在,则表示添加一个新的 “键:值” 对,也就是添加一个新元素。方法可以将另一个字典的 “键:值” 一次性全部添加到当前字典对象,如果两个字典中存在相同的 “键”,则以另一个字典中的 “值” 为准对当前字典进行更新。方法也可以用来为字典添加新元素。如果需要删除字典中指定的元素,可以使用。方法用于清空字典对象中的所有元素;方法也可以弹出并删除指定的元素。方法返回字典对象的浅复制。当以指定 “键” 为。原创 2024-08-01 23:14:40 · 189 阅读 · 0 评论 -
43 字典元素的访问
当使用 len()、max()、min()、sum()、sorted()、enumerate()、map()、filter() 等内置函数以及成员测试运算符 in 对字典对象进行操作时,也遵循同样的约定。③ 字典对象的 setfault() 方法用于返回指定 “键” 对应的 “值”,如果字典不存在该 “键”,就添加一个新元素并设置该 “键” 对应的 “值”(默认为 None)。② 字典对象提供了一个 get() 方法来返回指定 “键” 对应的 “值”,并且允许指定该键不存在时返回特定的 “值”。原创 2024-08-01 20:02:29 · 391 阅读 · 0 评论 -
42 字典创建与删除
序列,字典中的每个元素包含用冒号分隔开的 “键” 和 “值” 两部分,表示一种映射或对应关系,也称为关联数组。定义字典时,每个元素的 “键” 和 “值” 之间用冒号分隔,不同元素之间用逗号分隔,所有的元素放在一对大括号 “{ }” 中。使用赋值运算符 “=” 将一个字典赋值给一个变量即可创建一个字典变量。与其他类型的的对象一样,当不再需要时,可以直接删除字典。可以使用内置类 dict 以不同形式创建字典。字典(dict)是包含 “键:值” 元素的。,“值” 是可以重复的。原创 2024-08-01 18:07:41 · 364 阅读 · 0 评论 -
41 生成器推导式
当所有元素访问结束以后,如果需要重新访问其中的元素,必须重新创建该生成器对象。__() 方法或内置函数 next() 进行遍历,或者直接使用 for 循环来遍历其中的元素。但是不管用哪种形式,只能从前往后正向访问其中的元素,生成器对象类似于迭代器对象,具有惰性求值的特点,只在需要时生成新元素,比列表推导式具有更高的效率,空间占用非常少,尤其适合大数据处理的场合。生成器推导式也称为生成器表达式(generator expression),用法与列表推导式非常相似,在形式上。,也可以使用生成器对象的__原创 2024-07-31 19:03:29 · 286 阅读 · 0 评论 -
40 元组与列表的异同点
以及使用 count() 方法统计元素的出现次数和 index() 方法获取元素的索引,len()、map()、filter()等大量内置函数和 +、*、+=、in 等运算符也都可以作用于列表和元组。虽然列表和元组有着一定的相似之处,但在本质上和内部实现上都有着很大的不同。一般来说,并不需要关心该函数的返回值具体是什么,重点是对象是否可哈希,如果对象不可哈希会抛出异常。例如,调用函数时使用元组传递参数可以防止在函数中修改元组,而使用列表则很难保证这一点。从一定程度上讲,可以认为。,因为列表是可变的。原创 2024-07-31 18:15:39 · 513 阅读 · 0 评论 -
39 元组创建与元素访问
元组(tuple) 正是这样一种类型。在形式上,元组的所有元素放在一对原括号中,元素之间使用逗号分隔,列表的功能虽然很强大,但负担也很重,在很大程度上影响了运行效率。有时并不需要那么多功能,很希望能有个。很多内置函数的返回值也是包含了若干元组的可迭代对象,如 enumerate()、zip() 等。原创 2024-07-31 17:48:43 · 216 阅读 · 0 评论