This commit is contained in:
KBKUN024 2025-06-12 15:16:36 +08:00 committed by GitHub
commit 08bc5eba67
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 28 additions and 7 deletions

1
.gitignore vendored
View File

@ -14,3 +14,4 @@ __pycache__
### VisualStudioCode Patch ###
# Ignore all local history of files
.history
.DS_Store

View File

@ -96,7 +96,7 @@ class Triangle(object):
上面的代码使用`staticmethod`装饰器声明了`is_valid`方法是`Triangle`类的静态方法,如果要声明类方法,可以使用`classmethod`装饰器如上面的代码15~18行所示。可以直接使用`类名.方法名`的方式来调用静态方法和类方法,二者的区别在于,类方法的第一个参数是类对象本身,而静态方法则没有这个参数。简单的总结一下,**对象方法、类方法、静态方法都可以通过“类名.方法名”的方式来调用,区别在于方法的第一个参数到底是普通对象还是类对象,还是没有接受消息的对象**。静态方法通常也可以直接写成一个独立的函数,因为它并没有跟特定的对象绑定。
这里做一个补充说明,我们可以给上面计算三角形周长和面积的方法添加一个`property`装饰器Python 内置类型),这样三角形类的`perimeter`和`area`就变成了两个属性,不再通过调用方法的方式来访问,而是用对象访问属性的方式直接获得,修改后的代码如下所示。
这里做一个补充说明,我们可以给上面计算三角形周长和面积的方法添加一个`property`装饰器Python 内置类型),这样三角形类的`perimeter`和`area`就变成了两个属性,不再通过调用方法的方式来访问,而是用对象访问属性的方式直接获得。`property`装饰器会**自动调用对应的方法并返回计算结果**让代码更加简洁优雅,这样我们就不需要写`t.perimeter()`和`t.area()`了。值得注意的是,在类中访问时,同样要使用访问属性的方式,即:`self.perimeter`而不是`self.perimeter()`。修改后的代码如下所示。
```python
class Triangle(object):

View File

@ -24,6 +24,11 @@ class Suite(Enum):
```python
for suite in Suite:
print(f'{suite}: {suite.value}')
# 输出:
# Suite.SPADE: 0
# Suite.HEART: 1
# Suite.CLUB: 2
# Suite.DIAMOND: 3
```
接下来我们可以定义牌类。
@ -68,7 +73,7 @@ class Poker:
def shuffle(self):
"""洗牌"""
self.current = 0
self.current = 0 # 将发牌位置设置为0意思是从头开始发牌
random.shuffle(self.cards) # 通过random模块的shuffle函数实现随机乱序
def deal(self):
@ -130,7 +135,15 @@ for player in players:
执行上面的代码会在`player.arrange()`那里出现异常,因为`Player`的`arrange`方法使用了列表的`sort`对玩家手上的牌进行排序,排序需要比较两个`Card`对象的大小,而`<`运算符又不能直接作用于`Card`类型,所以就出现了`TypeError`异常,异常消息为:`'<' not supported between instances of 'Card' and 'Card'`。
为了解决这个问题,我们可以对`Card`类的代码稍作修改,使得两个`Card`对象可以直接用`<`进行大小的比较。这里用到技术叫**运算符重载**Python 中要实现对`<`运算符的重载,需要在类中添加一个名为`__lt__`的魔术方法。很显然,魔术方法`__lt__`中的`lt`是英文单词“less than”的缩写以此类推魔术方法`__gt__`对应`>`运算符,魔术方法`__le__`对应`<=`运算符,`__ge__`对应`>=`运算符,`__eq__`对应`==`运算符,`__ne__`对应`!=`运算符。
为了解决这个问题,我们可以对`Card`类的代码稍作修改,使得两个`Card`对象可以直接用`<`进行大小的比较。这里用到技术叫**运算符重载**Python 中要实现对`<`运算符的重载,需要在类中添加一个名为`__lt__`的魔术方法。很显然,魔术方法`__lt__`中的`lt`是英文单词“less than”的缩写以此类推魔术方法`__gt__`对应`>`运算符greater than魔术方法`__le__`对应`<=`运算符,`__ge__`对应`>=`运算符,`__eq__`对应`==`运算符,`__ne__`对应`!=`运算符。
六个比较方法的缩写:
- __lt__: less than (<)
- __gt__: greater than (>)
- __le__: less than or equal (<=)
- __ge__: greater than or equal (>=)
- __eq__: equal (==)
- __ne__: not equal (!=)
修改后的`Card`类代码如下所示。

View File

@ -2,7 +2,7 @@
### 正则表达式相关知识
在编写处理字符串的程时,经常会遇到在一段文本中查找符合某些规则的字符串的需求,正则表达式就是用于描述这些规则的工具,换句话说,我们可以使用正则表达式来定义字符串的匹配模式,即如何检查一个字符串是否有跟某种模式匹配的部分或者从一个字符串中将与模式匹配的部分提取出来或者替换掉。
在编写处理字符串的程时,经常会遇到在一段文本中查找符合某些规则的字符串的需求,正则表达式就是用于描述这些规则的工具,换句话说,我们可以使用正则表达式来定义字符串的匹配模式,即如何检查一个字符串是否有跟某种模式匹配的部分或者从一个字符串中将与模式匹配的部分提取出来或者替换掉。
举一个简单的例子,如果你在 Windows 操作系统中使用过文件查找并且在指定文件名时使用过通配符(`*`和`?`),那么正则表达式也是与之类似的用 来进行文本匹配的工具,只不过比起通配符正则表达式更强大,它能更精确地描述你的需求,当然你付出的代价是书写一个正则表达式比使用通配符要复杂得多,因为任何给你带来好处的东西都需要你付出对应的代价。
@ -148,8 +148,8 @@ print(purified) # Oh, *! 你是*吗? * you.
import re
poem = '窗前明月光,疑是地上霜。举头望明月,低头思故乡。'
sentences_list = re.split(r'[,。]', poem)
sentences_list = [sentence for sentence in sentences_list if sentence]
sentences_list = re.split(r'[,。]', poem) # ['窗前明月光', '疑是地上霜', '举头望明月', '低头思故乡', ''],注意,末尾有一个空字符串
sentences_list = [sentence for sentence in sentences_list if sentence] # 这行代码使用列表推导式过滤掉了空字符串。
for sentence in sentences_list:
print(sentence)
```

View File

@ -28,7 +28,14 @@
courses = ['语文', '数学', '英语']
# 录入五个学生三门课程的成绩
# 错误 - 参考http://pythontutor.com/visualize.html#mode=edit
# scores = [[None] * len(courses)] * len(names)
# 错误做法scores = [[None] * len(courses)] * len(names),得到如下的数据结构:
# [
# [None, None, None], # 指向同一内存地址
# [None, None, None], # 指向同一内存地址
# [None, None, None], # 指向同一内存地址
# [None, None, None], # 指向同一内存地址
# [None, None, None] # 指向同一内存地址
# ]
scores = [[None] * len(courses) for _ in range(len(names))]
for row, name in enumerate(names):
for col, course in enumerate(courses):