1. 匿名函数
常规函数:
python
def fun(x, y):
return x + y
匿名函数:
python
# lambda 空格后面是函数入参,冒号后面写函数体/函数逻辑
a = lambda x,y: x + y
print(a(2,3))
匿名函数/lambda函数的最大优点就是快速定义函数,使代码更精简。
使用lambda函数求列表所有数的平方和:
python
a = [1, 2, 3, 4, 5]
result = list(map(lambda x: x ** 2, a))
print(result)
from functools import reduce
result = reduce(lambda x, y: x + y, result, 0)
print(result)
上述过程中使用了map和reduce函数,类似于Java的流式操作,所不同的是Java中map和reduce是流对象的方法,而Python中map和reduce是内置函数,第二个参数是可迭代的集合。
还有filter操作:
python
a = [1, 2, 3, 4, 5]
result = list(filter(lambda x: x % 2 == 0, a))
print(result)
2. 变量作用域
根据变量作用域的划分,可以将变量分为全局变量和局部变量。对于整型全局变量,如果在函数中使用如下:
python
num1 = 10
def func():
num1 = 20
print(num1)
此时打印仍是10,因为num1在函数中被认为是定义一个局部变量,跟第一行的全局变量没有关系,即在函数中修改全局变量num1未生效。如果想真正修改全局变量num1,需要引入global关键字:
python
num1 = 10
def func():
global num1
num1 = 20
print(num1)
但如果全局变量是列表,则可以在函数中修改成功,不用引入global变量,这是因为列表是可变数据类型的,而数字、字符串和元组是不可变的。
3. random库
random库用来生成随机数
python
import random
# 生成0-1之间的随机小数
print(random.random())
# 生成1-100的随机整数,包括1和100
print(random.randint(1,100))
使用原始方法获取列表a中的随机一个数:
python
print(a[random.randint(0, len(a) - 1)])
使用random的api 获取列表a中的随机一个数:
python
print(random.choice(a)) # a可以为一个字符串
随机打乱一个列表:
python
print(random.shuffle(a)) # a可以为一个字符串
4. 正则表达式
python
import re
result = re.match("hello", "hello world!")
print(result)

结果表示匹配到了,是索引0-5的位置,匹配到的内容是hello
\d 匹配单个数字:
python
result = re.match(r"\d", "123456")
\d+匹配多个数字:
python
result = re.match(r"\d+", "123456")
\w匹配字母数字以及下划线:
python
result = re.match(r"\w+", "a8*6")
print(result)

\s匹配任意空白字符:
python
result = re.match(r"\s", " ")
$匹配结尾:
python
result = re.match(r"\s+$", " ad")
print(result)

^匹配开头:
python
result = re.match(r"^\s+$", " ")
.匹配任意字符:
python
result = re.match(r"^.+$", "waf-123")
\]表示可以匹配里面任意一个字符: ```python result = re.match(r"^[abcd]+$", "aaabbb") ``` \[\^\] 表示可以不匹配里面任意一个字符 \*表示匹配0个或多个,+表示匹配1个或多个: ```python result = re.match(r"^abcc+$", "abc") print(result) ```  ```python result = re.match(r"^abcc*$", "abc") print(result) ```  {}表示精准匹配次数: ```python result = re.match(r"^abc{2,5}$", "abcccc") ``` \|表示或: ```python result = re.match(r"^a|b|c$", "a") ``` #### 5. 时间库 获取当前时间的时间戳 ```python import time t = time.time() print(t) ``` 获取结构化的时间,年份 ```python t = time.localtime() print(t) print(t.tm_year) ``` 将结构化时间转化为字符串 ```python print(time.strftime("%Y %m %d %H:%M:%d", t)) ``` #### 6. socket库 socke库可以实现服务端和客户端的通信。首先创建服务端: ```python import socket # 创建socket对象 sk = socket.socket() # 绑定ip(本机)和端口号 sk.bind(("0.0.0.0", 8999)) # 设置监听,客户端个数为5个 sk.listen(5) # 等待客户端连接 conn, addr = sk.accept() print(conn) print(addr) ``` 然后创建客户端,使其连接服务端 ```python import socket # 创建socket对象 sk = socket.socket() # 连接服务器 sk.connect(("127.0.0.1", 8999)) ``` 客户端连接服务端后, 在服务端打印日志如下:  客户端发送数据: ```python import socket # 创建socket对象 sk = socket.socket() # 连接服务器 sk.connect(("127.0.0.1", 8999)) while True: send_data = input("请输入你要发送的内容") sk.send(send_data.encode('utf8')) # 服务器响应的数据 resp_data = sk.recv(1024) print(resp_data) ``` 服务器接收数据: ```python import socket # 创建socket对象 sk = socket.socket() # 绑定ip(本机)和端口号 sk.bind(("0.0.0.0", 8999)) # 设置监听,客户端个数为5个 sk.listen(5) # 等待客户端连接 conn, addr = sk.accept() print(conn) print(addr) While True: accept_data = conn.recv(1024) print("收到客户端的数据: " + accept_data.decode('utf8')) send_data = "收到" conn.send(send_data.encode('utf8')) ``` #### 7. 实例属性、类属性、实例方法、类方法 实例属性通过self.的方式来创建赋值或更新,比如在初始化函数中操作实例属性: ```python class Player: def __init__(self, name, age): self.name = name self.age = age ``` 通过.__dict__可以查看实例的所有属性(字典的形式): ```python tom = Player("tom", 24) print(tom.__dict__) ``` 类属性是所有实例共有的,定义在类中: ```python class Player: # 类属性 numbers = 0 def __init__(self, name, age): self.name = name self.age = age Player.numbers += 1 ``` 使用类属性需要使用类名.的方式: ```python print(Player.numbers) ``` 实例方法是实例才能调用的方法,与普通的函数的区别在于:1. 在类中;2. 第一个参数是self;3. 调用时使用实例.的方式。 ```python class Player: # 类属性 numbers = 0 def __init__(self, name, age): self.name = name self.age = age Player.numbers += 1 def show(self): print(self.name + " " + self.age) def show_attr(self): for k,v in self.__dict__.items(): print(k,v) tom = Player("tom", 24) tom.show() tom.show_attr() ``` 类方法是由@classmethod装饰器修饰的方法,第一个参数是cls,不通过实例来调用,通过类名.的方式来调用。 ```python class Player: # 类属性 numbers = 0 def __init__(self, name, age): self.name = name self.age = age Player.numbers += 1 def show(self): print(self.name + " " + self.age) @classmethod def show_numbers(cls): print(cls.numbers) tom = Player("tom", 24) Player.show_numbers() ``` #### 8. 静态方法 静态方法由@staticmethod装饰器来修饰,表示这个方法跟类与实例都不想关,第一个参数既不是cls,也不是self。 调用静态方法也是通过类名.的方式。 ```python class Player: # 类属性 numbers = 0 def __init__(self, name, age): self.name = name self.age = age Player.numbers += 1 def show(self): print(self.name + " " + self.age) @classmethod def show_numbers(cls): print(cls.numbers) @staticmethod def is_valid(**kwargs): pass tom = Player("tom", 24) Player.show_numbers() ``` #### 9. 面向对象三大特性:继承、多态、封装 继承:子类继承父类,子类可以继承父类的属性,也可以有自己的一些独有属性,还可以调用或者覆写父类的方法。Python中继承父类使用"(Parent)"的方式: ```python class VIP(Player): def __init__(self, name, age, level): # 调用父类初始化函数 super(name, age) self.level = level tom = VIP("tom", 24) print(type(tom)) print(isinstance(tom, Player)) print(isinstance(tom, VIP)) ```  多态:同一个父类的不同子类,都拥有同名的方法,但是实现不一样,即多种形态。比如Python中的加号"+",对于整数进行加号运算,就是求和,但是对于字符串进行加号运算,就是拼接了。 ```python class Animal: def speak(self): print(" ") class Cat(Animal): def speak(self): print("喵喵喵") class Dog(Animal): def speak(self): print("汪汪汪") def speak(obj: Animal): obj.speak() animal = Animal() kitty = Cat() puppy = Dog() speak(animal) speak(kitty) speak(puppy) ``` 封装:一个类、一个函数都算是封装,使用者只需要知道函数和类的功能,而无需关注其内部实现细节。Python中没有严格私有属性的概念,如果希望一个属性是私有的,可以在属性前加1个下划线表示受保护不能随便使用(只是一个约定),但只是希望如此,并非真正能保护,因为还是可以通过实例.属性名的方式访问到,如果想要真正保护属性,可以加上两个下划线: ```python class User: def __init__(self, name, age): self._name = name self.__age = age tom = User("tom", 24) print(tom._name) # 能访问 print(tom.__age) # 不能访问 ``` 函数也是类似的,通过前面加上双下划线来保护。但是可以通过其它方式来访问实例的私有属性和调用私有方法(加上_类名): ```python print(tom._User__age) # 可以访问 ``` 使用dir内置函数查看对象的所有属性和方法(包括私有的): ```python print(dir(tom)) ``` 既然私有属性不能随便访问,需要提供get/set方法来获取/修改私有属性: ```python class User: def __init__(self, name, age): self._name = name self.__age = age def get_age(self): return self.__age def set_age(self, age): self.__age = age tom = User("tom", 24) tom.set_age(25) print(tom.get_age()) ``` 使用装饰器@property和@setter来简化代码: ```python class User: def __init__(self, name, age): self._name = name self.__age = age # 将函数变为变量,不能再当做方法来调用 @property def age(self): return self.__age # 变量修改器 @age.setter def age(self, age): self.__age = age tom = User("tom", 24) tom.age = 25 print(tom.age) ``` 这样做似乎与直接将age变为公有变量是一样的,都是调用tom.age来获取或者修改属性值,但是这样的好处是在setter方法中可以做一些必要的校验,如果直接将age设为公有变量,修改值时是直接修改没法校验的。 #### 10. 魔法方法 Python中的魔发方法是以两个下划线开头的,在进行某些特殊的操作(比如运算符操作、转化为字符串等等)时,会调用到这些魔法方法。比如上述类的初始化魔法方法,就是在创建对象完之后会自动调用的方法。如果想将对象转换为字符串,可以重写__str__方法: ```python def __str__(self): return self.name + ": " + self.age ``` 在调用str(对象)时,就会调用上面的__str__方法。 如果想对实例进行加法运算,可以重写__add__方法: ```python def __add__(self, other): return self.name + other.name ``` 如果想对实例进行是否相等的判断,可以重写__eq__方法: ```python def __eq__(self, other): return self.name == other.name ```