Python基础

一、Python背景介绍

Python是一种面向对象的编程语言,由吉多·范罗苏姆开发,1991年发布,它常被昵称为胶水语言,能够把其他语言之作的各种模板连接在一起

1.Python解释器

  • Cpython
  • PyPy
  • Jython

2.Python的优点

  • 简单易学
  • 第三方库很丰富
  • 可移植
  • 既面向过程又面向对象

3.Python的缺点

  • C语言是编译型语言,Python是解释型语言
  • 代码不能加密
  • 强制缩进
  • GIL全局解释器锁

4.Python就业方向

  • Web后台开发
  • 爬虫开发
  • 数据分析
  • 运维开发
  • 机器学习
  • 人工智能

二、基本语法

1.流程控制

1.if语句

score = int(input("请输入您的成绩:"))
if score < 60: # python中无需括号,但是要注意一定要有冒号
    print("成绩不合格") # python中"和'一样
    pass
elif score < 70: # python中没有switch函数
    print("成绩合格")
    pass
elif score < 90:
    print("成绩不错")
    pass
else: # else为可选条件
    print("成绩优秀")
    pass

# if语句单行写法(相当于java中的?:)
c = a if a>b else b

2.while语句

  • 必须有初始值
  • 需要条件表达式
  • 需要终止条件
# 打印等腰三角形
row = 1
while row <= 5: # 条件表达式
    j = 1
    while j < = 5-row:
        print("")
        j+=1
        pass
    k = 1
    while k < = 2*row - 1:
        print("*")
        k+=1
        pass
    print()
    row+=1
    pass

3.for循环

  • range(起始,结束,步长),步长不能为0,其中结束为开区间
  • break表示退出当前循环
  • continue表示跳过此次循环
# 简单的加法
sum = 0
for item in range(1,51): # item是一个临时变量
    if sum > 100:
        print("循环执行到%d就退出来了"%item)
        break
        pass
    sum += item
    pass
print("sum=%d"%sum)

2.高级数据类型

1.字符串(str)

1.常用方法
# 1.首字母转换为大写
name.capitalize(); 
# 2.查看对象内存地址
id(name)
# 3.检查对象是否以x结束/开始,输出为布尔值
name.endswith("p")
name.startswith("p")
# 4.返回查找的第一个索引的值,没找到返回-1
name.find("e")
# 5.判断是否为全小写
name.islower()
# 6.字符串全部大小写转换
name.lower()
name.upper()
# 7.大写变小写,小写变大写
name.swapcase()
# 8.把每个单词的首字母变成大写
name.title()
# 9.统计出现的次数
name.count()
# 10.切片操作
name[start:end] # 相当于substring,不包括end
name[start:] # 表示从start索引开始到最后
name[:end] # 表示从开始到end
name[::-1] # 倒序输出
# 11.替换字符
name.place(old,new,count = None) # old表示就字符,new为替换字符串,count为替换个数,None表示全部替换

2.列表(list)

  • list是一种有序的集合,可以随时添加和删除其中的元素
  • 列表的下表取值/切片/是否越界与字符串一致,区别就是列表获取元素
1.常用方法
# 1.定义列表
list = ["peter", 26, "school", "python engineer"] # 主义为中括号
# 2.修改数据
list[0] = "faker" # 括号内为索引值
# 3.删除元素
del list[0] # 单个删除
del list[1:3] # 批量删除,与基本切片操作语法一样
# 4.remove()
list.remove("peter") # 移除具体的元素,如果元素不存在会报错,如果有多个该元素只会删除第一个
# 5.pop()
list.pop(1) # 移除指定项,参数是索引值,如果不填参数,则删除最后一个元素
# 6.index()
list.index() # 获取指定的元素的索引值,如果有多个相同元素,则返回第一个的索引值
# 7.insert()
list.insert(1,"ss") # 在索引值之前插入元素
# 8.append()
list.append("ss") # 在列表后面追加元素
# 9.count()
list.count(26) # 统计某元素出现的次数
# 10.extend()
list.extend([1,2,3,4]) # 扩展,相当于批量添加,注意添加的元素必须为列表,区分与append的区别
# 11.遍历list
for item in list:
    print(item)

3.元组(tuple)

  • 不可变
  • 内部元素可以是任何类型(包括list类型)
  • 除了不能修改,其他的搜索方法均可适用
1.常用方法
# 1.创建元组
tuple = (1,) # 单个元素需要加,
cre_tuple = (("1","2","3")) # 注意双括号
tuple = ("peter",26,"school",[1,2,3,4]) # 用()创建元组
# 2.更改元组中的列表元素
tuple[3][0] = 10 # 元组类型不能改变,但其中的列表类型可以修改
# 3.转换为列表
tes_list = list(cre_tuple)

4.字典(dict)

  • 以键值对的形式创建
  • 键不能重复,且只能是不可变的类型,如数字,字符串和元组,但值可以重复
  • 通常用键来访问数据,支持增删改查
  • 不是序列类型,没有索引的概念,是一个无序的键值集合
1.常用方法
# 1.定义字典
dict = {"fff":"string",12:(1,2,3)} # 适用{}定义字典
dic = dict() # 用dict()定义
# 2.添加
dict["name"] = "peter"
dict["age"] = 26
# 3.len
len(dict) #字典的键值对数
# 4.修改
dict["name"] = "peter" # 可以直接通过键修改
dict.update({"age":26}) # 添加或更新
# 5.keys()
dict.keys() # 获取所有键
# 6.values()
dict.values() # 获取所有值
# 7.遍历
for i,j in dict: 
# 8.查找元素
dict["name"] # 这种方式如果找不到对应的key,会报一个KeyError错误
dict.get("name") # 这种方式不会引发KeyError,会返回一个默认值(None)
dict.get("name", "找不到名称") # 返回一个默认值“找不到名称”
dict.setdefault("name", "找不到名称") # 该方法同get

5.集合(set)

  • 无序且不重复的元素集合
  • 不支持索引和切片,因为是无序的
1.常用方法
# 1.创建集合
set1 = ["1","2"] 
# 2.类型转换
list1 = [1,5,4]
set1 = set(list1)
# 3.添加元素
set1.add("python")
# 4.清空集合
set1.clear()
# 5.移除指定数据
set1.discard("1")

6.公用方法

1.合并操作(+)
  • 列表、字符串、元组都能合并,但不适用于字典
strA = "hello"
strB = "world"
strC = strA + strB
2.复制操作(*)
strB = strB * 3
3.判断对象是否存在(in)
"A" in strA
4.排序方法(sorted)
sorted([1,2,3,5,6,9], reverse=True)
5.范围函数(range)
range(start,stop,step) # 不包含stop
6.打包函数(zip)
  • 函数用于将可迭代对象作为参数,将对象中对应的元素打包成一个个元组,然后返回这些元组组成的列表
  • 如果各个迭代器的元素个数不一致,则返回列表长度与最短的对象相同
a = zip([1,2,3],['a','b','c'])
7.枚举函数(enumerate)
  • 该函数用于将一个可遍历的数据对象组合成一个索引序列,同时列出数据和数据下标,一般用于for循环
  • 默认从0开始计数
# 列表索引
list = ["o","b","j"]
for index,i in enumerate(list):
    print(index,i)
# 字典索引
dict = {"name":"周杰伦","hobby":"唱歌","pro":"艺术"}
for i in enumerate(dict):
    print(i) # 只对键进行索引

3.常用函数

1.print()

print(a)

2.type()

# 查看变量a的数据类型
type(a)

4.各类运算符

1.算术运算符

算术运算符功能
+
-
*
/
%取余
//地板除,相除取整
**指数,左底右幂

2.逻辑运算符

优先级:()>not>and>or

  1. or
  2. and
  3. not

3.运算函数

# 1.求绝对值
abs(num)
# 2.四舍五入
round(1.232,2) # 后面的参数表示保留几位小数
# 3.求最大值
max(num)
# 4.求最小值
min(num)
# 5.求和
sum(a+b)
# 6.执行字符串表达式
eval("a+b+c")

5.字符串输入输出

1.输入

# input
name = input("请输入您的姓名:") # input获取的所有类型都是str类型的
a = int(input()) # 转换类型

2.输出

1.格式化输出符号
格式化输出符号对应类型
%c字符
%s字符串
%i有符号十进制整数
%d有符号十进制整数
%u无符号十进制整数
%o八进制整数
%x十六进制整数
%e索引符号
%E索引符号
%f浮点实数
%g%f和%e的简写
%G%f和%E的简写
name = "peter"
age = 26
print("我的名字是%s,今年%d"%(name,age)) 
2.格式化输出
# format
print("姓名:{}".format(name))
print("QQ:{}".format(QQ)) # 不需要指定数据类型

6.定义函数

1.定义参数

# 1.定义函数
def printInfo(n):
    '''
    这个函数用来打印信息
    param n:打印次数
    return:返回信息
    '''
    print("hello\n"*n)
    pass
# 2.必选函数
def sum(a,b): # a,b为必选参数,不能省略
    sum = a+b
    pass
# 3.默认参数(缺省参数)
def sum(a,b = 30): # b为默认参数,默认参数必须放在参数列表最后面
    sum = a+b
    pass
# 4.可变参数
def getComputer(*args): # *定义可变参数,args为元组类型
    result = 0;
    for i in args:
        result+=i
        pass
    pass
# 5.关键字可变参数(必须放到可选参数之后)
def keyFunc(**kwargs): # 用**来定义参数,参数关键字是一个字典类型,key是一个字符串
    pass
# 6.返回值
'''
如果在函数内部有return,则返回实际值
如果执行了return,则执行完退出
'''
def sum(a,b):
    sum = a+b
    return sum
# 冒号作用:参数的类型建议符
# 箭头:函数返回值的类型建议符
def sum(a:int,b:int) -> int:
    sum = a+b
    return sum

2.匿名函数

# 用lambda关键字来创建匿名函数
# 特点:冒号后面的表达式有且只有一个
# 匿名函数自带return,且这个return结果就是表达式计算后的结果
# 缺点:只能是单个表达式,不是一个代码块,其设计就是为了满足简单函数的场景
M = lambda x,y:x+y
print(M(23,19))

3.主函数调用

if __name__="__main__":
    main()
  • 这个脚本被执行的时候,name 值就是 main ,才会执行 main()函数

  • 如果这个脚本是被 import 的话,__name__的值不一样。main()函数就不会被调用。

  • 这个句子用来写既能直接运行,又能给其他python程序import,提供库调用的脚本

7.定义变量

1.局部变量

  • 局部变量势函数内部定义的变量,作用于仅局限在函数的内部
  • 不同函数可以定义相同的局部变量

2.全局变量

# 当全局变量与局部变量出现重复定义时,优先执行局部变量
# 函数内部修改全局变量是无效的
name = "Peter"
def editName():
    name = "Peter" 
    pass
def globalEditName():
    global name # 在函数内部对全局变量进行修改,需要global关键字声明
    name = "Peter"
    pass

三、类和对象

# 定义类
class Person: # 建议定义类名时首字母大写
    name = "Peter"
    age = 26 # 类属性
    def _init_(self): 
        self.color = "黄" # 实例属性
        pass
    def eat(self): # 实例方法
        print("大口吃饭")
        pass
    pass
yq = Person() # 实例化,创建对象
Person.name # 访问类属性
yq.color # 访问了类属性
yq.eat() # 调用方法

1.类属性

  • 类属性是所有对象公用一份的,指向同一地址
  • 类属性不能通过实例对象直接修改
Person.name="PPPAAA" # 只能通过类名修改
yq.name = "aaa" # 实例对象的属性修改后,另一个对象的name并不会改变

2.类方法

实例方法,不同与普通函数,必须包含self参数,也可以不用self作为关键字,但一定不能少

  • self和对象指向同一内存地址,可以认为self就是对象的引用
  • self可以理解为对象自己,相当于java中的this
  • 某个函数调用其方法时,python解释器会把这个对象作为第一个参数传递给self
  • 特点:只有在类中定义实例化方法时才有意义,在调用时不必传入相应的参数,解释器会自动去指向

3.魔术方法

python中内置的方法,方法名为"_XXX_",在进行特定操作时会被调用

1._init_()

# 创建对象时自动调用,无需手动调用
# 用来做数据初始化工作,也可以认为是实例的构造方法
class Animal:
    def __init__(self,name,color="red"):
        self.name = name
        self.color = color
        pass

2._str_()

# 将对象转换成字符串str测试时,打印对象信息
# 如果不加此方法,会输出内存地址
class Aninaml:
    def __str__(self):
        return "它的名字是%s,他的颜色是%s"%(self.name,self.color)

3._new_()

  • new先执行,再执行init
# 创建并返回一个实例对象
# 实例化方法必须要返回该实例,否则对象创建不成功,必须要有return这行语句
class Animal:
    def __new__(cls,*args,**kwargs):
        print("hello world")
        return super().__new__(cls) # python默认的__new__结构

4._class_()

# 获得已知对象的类
对象.__class__()

5._del_()

# 对象在程序运行结束后进行对象销毁时调用该方法,以释放内存资源
# 当一个对象被删除或销毁时,python解释器默认调用一个析构方法
class Animal:
    def __del__(self):
        print("该对象已被删除")

6._call_()

# 如果一个对象定义了 __call__ 方法,那么这个对象就可以作为一个函数调用
class MyCallableClass:
    def __call__(self, *args, **kwargs):
        print('Called with arguments:', args, kwargs)

obj = MyCallableClass()

obj()
# 实际上,通过定义 __call__ 方法,可以将一个类的实例转化为可调用对象,这是类似于函数的对象,可以使用括号调用

4.类方法

类对象所拥有的方法称为类方法,需要用装饰器@classmethod来标识

  • 对于类方法第一个参数必须是类对象,一般以cls作为第一个参数
  • 类方法可以通过类对象直接调用,也可以通过实例对象调用
class Person:
    country = "China"
    @classmethod
    def get_country(cls):
        return print(country)
    pass
Person.get_country(); # 类方法可以通过类对象直接调用
a = Person()
a.get_country() # 也可以通过实例对象访问

5.静态方法

静态方法需要用@staticmethod来标识

  • 静态方法不需要任何参数
  • 静态方法主要用来存放逻辑型代码,本身和类以及实例对象没有交互,不涉及到类中方法和属性的操作
class Person:
    country = "China"
    @staticmethod
    def get_country():
        return Person.country

6.Property方法

可以使实例方法用起来像实例属性一样,对应于某个方法,使用property属性,简化调用者获取数据的流程

class Price:
    def __init__(self):
        self.__price = 100
        pass
    @property # getter方法
    def price(self):
        return self.__price
    @price.setter # setter方法
    def price(self,f):
        self.__price = f
        pass
    @price.deleter #deleter方法
    def price(self):
        del self.price

7.抽象方法

用于程序接口的控制,正如上面的特性,含有@abstractmethod修饰的父类不能实例化,但是继承的子类必须实现@abstractmethod装饰的方法

class Foo(ABC):
    @abstractmethod
    def fun(self):
        """
        你需要在子类中实现该方法, 子类才允许被实例化
        """

class SubFoo(Foo):
    def fun(self):
        print("子类实现父类的抽象方法")
  • ABC(Abstract Base Class)抽象基类:ABC 是 Python 中用于定义抽象基类的模块。抽象基类是具有一组共同特征的类的抽象表示。通过继承 ABC 类和使用 @abstractmethod 装饰器,可以定义抽象方法和属性
  • @abstractmethod:强制子类实现父类中指定的一个方法
  • 具体类可以继承抽象基类并实现其定义的抽象方法和属性

8.封装

1.私有化属性

  • 双下划线开头,声明该属性为私有
  • 不能在类的外部被使用或直接访问
  • 应用场景
    • 把特定的一个属性隐藏起来,不想让类的外部进行直接调用
    • 想保护这个属性,不让属性的值随意改变
    • 保护这个属性,不想让派生类去继承
# 可以通过类的方法来访问私有属性
class Student:
    __name = "小明"
    def get_name(self):
        print(self.__name)
        pass
    pass

2.私有化方法

  • 有些重要的方法,不允许外部调用,防止子类意外重写,把普通方法设置成私有化方法
class A:
    def _myname(self):
        print("小明")

3.下划线的说明

  • 单下划线表示protected类型的变量,保护类型只能允许其本身与子类进行访问,不能使用from xx import *的方式导入
  • 前后两个双下划线表示魔术方法
  • xxx_后面单下划线,是为了避免属性名与python关键字冲突,没有别的含义
  • 双下划线表示私有变量

9、继承

python中,子类可以继承多个父类

class XM(Person,Adult):
    def __init__(self,name,age,school):
        Father.__init__(self,name,age) # 这种方法参数需要保留self
        super().__init__(name,age) # 也可以用这种方式,二选一,参数不需要self
    def work(self): # 重写方法
        print("要工作") 

10、多态

python不支持java和C++这类强类型语言中多态的写法,但支持原生多态,崇尚鸭子类型

1.多态的前提

  • 必须存在继承关系
  • 子类重写父类的方法
  • 好处
    • 可以用同一种方法,根据不同对象作出不同应对

2.多态的实现

class Animal:
    def run(self):
        print("The animal is running")
		pass
    pass
class Dog(Animal):
    def run(self):
        print("The dog is running")
        pass
    pass
class Cat:
    def run(self):
        print("The cat is running")
        pass
    pass
def makeRun(animalType):
    animalType.run()  # 不一定要是Animal的子类

四、异常处理

python解释器检测到一个错误时,就无法继续执行,出现了错误的提示,这就是异常

1.异常的抛出机制

  1. 如果在运行时没有异常,解释器会查找相应的异常捕获类型
  2. 如果在当前函数里面没有找到的话,他就会将异常传递给上层的调用函数,看能否处理
  3. 如果最外层没找到,解释器就会退出,程序down掉
try:
    print(b) # 捕获异常代码
    pass
except NameError as msg: # 捕获到错误,会在这里执行,根据具体的错误类型来捕获
    print(msg)
    pass
else:
    print("未出现异常") # 未出现异常时执行
    pass
finally:
    print("程序运行结束") # 无论如何都会执行

2.主要的错误类型

  1. FileNotFoundError:找不到指定文件的异常
  2. NameError:未声明or未初始化对象(没有属性)
  3. BaseException:所有异常的基类(父类),即包含所有的异常
  4. SyntaxErrorPython:语法错误
  5. ZeroDivisionError:除(或取模)零(所有数据类型)
  6. Exception:万能异常类型,捕获所有异常,当对出现的问题或错误不确定的情况下可以使用

3.自定义异常类

  • 自定义异常,都要直接或间接继承Error或Exception类
  • 由开发者主动抛出自定义异常,在python中使用raise关键字
# 自定义一个异常类
class LeNumException(Exception):
    def __str__(self):
        return "[error]:你输入的数字小于0,请输入大于0的数字"
    pass

try:
    num = int(input("请输入一个数字:"))
    if num < 0:
        raise LeNumExcept()
except LeNumExcept as e:
    print(e) # 捕获异常
else:
    print("没有异常")

五、动态添加

运行时可以改变其结构的语言,例如新的函数、对象、甚至代码可以被引进,已有的函数可以被删除或是其他结构上的变化

1.动态添加属性

# python可以在程序运行过程中添加属性和方法
class Animal:
    def _init_(self,name,age):
        self.name = name
        self.age = age
        pass
    pass
cat = Animal("小白",5)
cat.color = "白色" # 动态绑定实例属性
print(cat.color)
Animal.food = "fish" # 动态添加类属性

2.动态添加方法

import types 
def dymicMethod(self):
    print("------")
    pass
zm.printInfo = types.MethodType(dynamicMethod,zm) # 动态绑定方法

@classmethod
def eat(cls):
    print("吃东西")
    pass
@staticmethod
def drink():
    print("喝水")
    pass

Animal.eat = eat # 给类绑定类方法
Animal.drink = drink # 给类绑定静态方法

3.__slots__属性

  • python是动态语言,在运行时可以动态添加属性,如果限制在运行时给类添加属性,python允许在定义class时,python允许在定义class时,定义一个特殊的__slots__变量,来限制该class实例能添加的属性
  • 只有在slots变量中的属性才能被添加,没有的属性会添加失败,这样可以防止其他人在调用类的时候不安全
  • 子类未声明slots变量时,不会继承父类中的slots属性,可以随意赋值属性;子类声明了slots变量后,范围是自身+父类的slots变量
  • 定义了slots变量后,__dict__不存在,节约了内存空间(所有的可用属性都会存储在__dict__中,但占用的内存空间很大)
class Student:
    __slots__ = ("name","age") # 只允许添加name和age属性,限制了添加的属性
# 但不会限制动态添加类属性

六、导包操作

1.模块

  • 一个模块可以被看做是一个文件,一个文件也可以被当做一个独立的模块被别的程序导入调用
  • 模块的文件名是模块的名字加上扩展名.py
  • 模块首次导入(或重载)时,python会立即执行模块文件的顶层代码(也即不在函数内的代码),而位于函数主体内的直到函数被调用后才会执行,之后的调用都是引用内存

2.模块的搜索

  • python的解释器在import模块时查找模块的顺序:

    1. 程序的主目录

    2. python的PATH目录(如果设置了此变量),可以使用以下命令查看python的PATH目录

    3. 标准链接库目录,就是python安装目录下的lib文件夹这个目录

    4. 任何.pth文件的内容(如果存在.pth文件)这四个组件组合起来即为sys.path所包含的路径,而Python会选择在搜索路径中的第一个符合导入文件名的文件

      import sys
      >>>sys.path
      

3.语法操作

1.import…as…

import numpy as np
# 这种方式调用模块内部函数时,需要np.xxx的形式
  • import语句导入指定的模块时会执行三个步骤
    1. 在指定路径下搜索模块文件,找到模块文件
    2. 指定的模块在被导入时就会被编译成字节码,即编译成.pyc文件
    3. 依靠模块的代码中的定义来创建其所定义的对象,模块文件中的所有语句回一次执行,从头至尾,而此步骤中任何对变量名的赋值运算,都会产生所得到的模块文件的属性
  • 注意:模块只在第一次导入时执行上述步骤,后续的导入操作只不过是提取内存中已加载的模块对象,可以使用reload()命令重新加载指定的模块

2.from…import…

from tensorflow.keras import data
# 只导入模块的部分属性或者函数,此时的函数可以直接调用而不用创建对象

七、IO流

1.文件操作

python自带文件的基本操作方法,但是借助OS等模块更加方便快捷

  • 文件操作的一般步骤
    1. 打开文件
    2. 读写文件
    3. 保存文件
    4. 关闭文件

2.打开文件

打开一个已存在的文件,或创建一个新文件

# windows默认的编码是GBK,这个是中文编码,最好的习惯是我们打开一个文件时给它制定一个编码类型
fobj = open("./Text.txt","w")
fobj = write("Hello World")
fobj.close()
# 以二进制形式写入数据
fobj = open("Text.txt","wb")
fobj.write("在乌云和大海之间",encode("utf-8"))
fobj.close()
  • 文件打开模式
    • r:以只读方式打开文件
    • w:打开一个文件只用于写入,如果文件已存在则将其覆盖,如果不存在,则创建新文件
    • a:打开一个文件用于追加,如果文件已存在,指针放在文件的结尾;新内容会被写入到已有内容之后。如果该文件不存在,则创建新文件进行写入
    • wb:以二进制的形式写入数据

3.读取数据

f = open("Text.txt","r")
print(f.read()) # 读取全部数据
print(f.read(12)) # 读取指定字符个数read(num)
print(f.readline()) # 按行读取,返回一行
# 二进制读取
f = open("Text.txt","rb")
data = f.read()
print(data)
print(data.decode("gbk")) # 需要解码
f.close()

4.with上下文管理

  • 优点:自动释放关联的对象
  • with语句:不管在处理文件过程中是否发生异常,都能保证with语句执行完毕后已经关闭打开的文件句柄
with.open("Text.txt","r") as f: # 以这种方式可以替代f.close()
    print(f.read())

八、内置函数

1.hasattr

用于检查对象是否具有特定的属性

  • 参数
    • object:需要检查的对象
    • name:需要检查的属性名称,必须是字符串
  • 输出
    • 如果对象具有指定的属性,则返回True,否则返回False
  • 用例
class Myclass:
    def __init__(self):
        self.attribute = "Hello"

object = MyClass()

if hasattr(obj, 'attribute'):
    print('obj has attribute attribute')
else:
    print('obj does not have attribute attribute')

2.yield

用于定义生成器函数,生成器函数可以在每次被调用时生成一个值,而不是一次性生成所有值并将其存储在内存中

def my_generator():
    yield 1
    yield 2
    yield 3

# 调用生成器函数,返回一个生成器对象
my_gen = my_generator()

# 1.使用生成器对象进行迭代
print(next(my_gen))  # 输出: 1
print(next(my_gen))  # 输出: 2
print(next(my_gen))  # 输出: 3

# 2.利用for循环来进行迭代
for item in my_generator():
    print(item)
  • 调用next()函数时,生成器函数会从上次停止的地方继续执行,直到遇到yield
  • yeild返回一个值并暂停函数的执行,直到下一次调用
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值