python 入门基础 Introduction to Python Fundamentals

这篇具有很好参考价值的文章主要介绍了python 入门基础 Introduction to Python Fundamentals。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

注释

单行注释
# 注释
print(0)
多行注释
'''
这是一个注释
'''
print(0)

pass

补充语法的完整性,什么都不做

if 1 > 1:
    pass
else:
    print("123")

字符串格式化

format
info = '我叫{0},我的年龄是{1}岁'.format('张三',101)
info = '我叫{},我的年龄是{}岁'.format('张三',101) # 按照顺序填入值
info = '我叫{name},我的年龄是{age}岁'.format(name='张三',age=101) # 不常用,相当于{}内的是一个变量名
%
info = '我叫%s,我的年龄是%d岁' %('张三',101)
f-string(py3.6之后可用)
name = '张三'
age = 101
info =  f'我叫{name},我的年龄是{age}岁'

数据结构

数据类型的转换:目标类型(值),如int(‘1’),将浮点值转换为整型值会丢失精度

  • 在函数中修改全局变量的值需要用global关键字再次声明全局变量,以表明修改的是全局变量而不是声明的局部变量

    • num = 10
      def add():
          global num
          num += 10
      add()
      print(num) # 20
      
  • nonlocal用法与global类型,但常用于嵌套函数中

    • def demo1():
          num = 10
          def demo2():
              nonlocal num
              num += 10
          demo2()
          return num
      
      print(demo1()) # 20
      
int
a = 1
b = 2
str
name = 'zhangsan'
hobby = 'PLAY'
age = '18'
res = name.upper() # 大写
res = hobby.lower() # 小写
age.isdecimal() # 返回true or false,判断是可以转换为数字
name.isalpha() # 判断是否是字母
age.isdigit() # 判断是否是数字
age.isalnum() # 判断是否是数字字母混合
name.startswith('zhang') # 判断是否是zhang开头
name.endswith('san') # 判断是否是san结尾
name.replace('zhang','li') # 替换旧值为新值
addr = '河南省 郑州市 郑东新区'
res = addr.split(' ') # 切割返回一个list ['河南省', '郑州市', '郑东新区']
res = addr.split(' ',maxsplit=1) # 切割返回一个list,从左到右只切割一次 ['河南省', '郑州市 郑东新区']
res = addr.rsplit(' ') # 从右往左切割
addr = '_'.join(res) # 将列表res中的值以_连接
addr = addr.strip()/rstrip()/lstrip() # 去除字符串两端/右边/左边空白
add.partition(' ')/rpartition(' ') # 将字符串按照空格切割成元组,从左到右/从右往左
len(name) # 获取长度
name[0] # z 获取单个字符
name[-1] # n
name[1:2] # h
name[:1] # z
name[5:] # san
s = 'ang' in name # 判断字符串是否包含某个子序列
bool

当类型转换为bool时,只有0、空字符串、空列表、空元组、空字典以及None转为False,其他都为True

a = True
b = False
float
a = 3.14
列表(list)

长度可变,可以存放任意类型的数据,有序

# 列表初始化
l = [] # 方式1
ll = list() # 方式2
# 添加元素
l.append(1) # 向列表尾部添加元素
l.extend([2,3,4]) # 向列表尾部添加多个元素
l.index(1,5) # 向列表中索引位置为1的位置添加元素
# 删除元素
l.remove(2) # 删除元素指定的元素,若删除的元素在列表中出现多次就删除最先出现的元素
del l[1] # 删除列表中索引为1的元素
l.clear() # 清空列表
# 反转列表,在原列表中调整元素的顺序,不会产生新的列表
l = reversed(l)
# 获取指定元素在列表中出现的次数
l.count(3) # 统计的元素不存在,不会报错,会返回0
# 弹出元素,并从列表中删除
l.pop() # 默认弹出列表末尾的元素,可以指定要弹出元素的索引,如l.pop(1),列表为空或超出索引会报错
# 合并列表
t = [34,32]
lis = t + l
# 复制列表中的元素
# 将list对象与正整数相乘会复制列表中的元素,复制的次数取决于参与运算的正整数
print(t*2) # [34,32,34,32]
字典(dict)

存放键值对,val可以是任何类型,key只能是可hash类型,key不可重复

# 初始化
d = {'name':'张三','age':11}
dd = dict(age=18)
dd['name'] = 'lisi'
# items返回一个迭代器,使用for循环可以获取到每个键值对,items返回的是一个元组列表
for k,v in d.items():
    print(f'{k}:{v}')
# 删除
del d['name']
'''
更新update(),可以接收多种参数,
1、关键字参数,直接将参数名作为key参数值为val
2、另外一个字典,将另一个字典中的键值对复制到当前字典对象中,若key已存在将覆盖当前字典中的val
3、序列对象,tuple、list
'''
d.update(name='wangwu')
d.update({'name':'wangwu'})
d.update((('name','wangwu'),))
# 合并字典,ChainMap合并对象中出现相同的key时只会返回第一个key的值,
# ChainMap对象的删除、设置等操作只对ChainMap中的第一个字典对象有效
from collections import ChainMap
cm = ChainMap(d,dd)
# 计数器Counter,key存储某个序列中的元素,val存储元素出现的次数
c = Counter('123112') # 返回一个特殊的字典
print(c.most_common()) # 返回一个列表,将按照元素出现次数进行降序排列
集合

不能有重复元素,有序

# 初始化
s = set([1,2,3,6]) # 初始化之后可以使用add、remove方法来修改元素
f = frozenset([1,2,3]) # 初始化之后不能再修改
ss = {1,2,3,4} 
# 合并集合
s = s.union(ss) # 方式1
print(s) # {1,2,3,4}
s = s | ss # 方式2
print(s) # {1,2,3,4}
# 包含关系
s.issuperset(ss) # False 当前集合是否为另一个集合的父集(超集),即另一个集合中的所有元素是否都出现在当前集合中,或两个集合的元素完全相同
s.issubset(ss) # True 当前集合是否为另一个集合的子集,即当前集合的元素全部在另一个集合中,或两个集合的元素全部相同
# 交集,获取集合的共有元素
s.intersection(ss) # {1,2,3}将计算结果存放到新的集合中,并返回给调用方
s.intersection_update(ss) # 添加_update后缀的作用是更新当前集合并存储结果
s = s & ss
# 差集,获取当前集合与其他集合存在差异的元素
ss.difference(s) # {4}
ss.difference_update(s)
ss = ss - s
# 异或,排除集合之间的共同元素之后,所剩下的元素
s.symmetric_difference(ss) # {4, 6}
s.symmetric_difference_update(ss)
s = s ^ ss
枚举
from enum import Enum,IntEnum
# 枚举需要使用class关键字定义,且必须从Enum或其子类派生
# 枚举默认是可以出现重复的成员值,使用@unique装饰器,就不能出现重复成员值,否则会报错
class MyEnum(Enum):
    SINGLE = 1
    MUTIL = 2
# 调用
e = MyEnum.SINGLE
# 只能使用int值的枚举
class MyEnum(IntEnum):
    SINGLE = 1
    MUTIL = 2
迭代器
# iter()函数是将传入的对象转换为迭代器
# next()函数可以在一个迭代器上多次调用,每次调用都会返回一个元素,若没有可以返回的元素,就会报错
i = iter([1,2,3])
while True: # 1 2 3
    try:
        print(next(i))
    except StopIteration:
        break
# yield只能在函数内部使用,当函数中存在yield时,函数就会返回一个迭代生成器对象
def t():
    yield 1
    yield 2
t = t()
print(next(t)) # 1
print(next(t)) # 2

def t():
    x = yield 1 # 赋值语句从右往左执行,调用第一次next时输出1,第二次调用next时会将yield 1替换为None
    yield x
t = t()
print(next(t)) # 1
print(next(t)) # None
# 自定义迭代器,只要类型中实现下面两个方法即可
# __iter__方法由iter函数调用
# __next__方法由next函数调用
class MyIter:
    def __iter__(self):
        pass
    def __next__(self):
        pass
其他
# 自定义序列
# 实现下面三个方法就可以以索引的方式访问元素
def __getitem__(self,index)
def __setitem__(self,index,val)
def __delitem__(self,index)
# 获取序列的长度,可以是类型对象占用的空间或对象包含的元素个数
def __len__(self) # 当对象传递给len函数后调用

# 切片obj[start:end:step]
a = [1,2,4,6,7]
print(a[:2]) # [1, 2]
print(a[2:]) #[4, 6, 7]
print(a[::2]) # [1, 4, 7]
print(a[:-1]) # [1, 2, 4, 6]
# in/not in检查元素是否存在某个序列
print(1 in a) # true
print(3 not in a) # true
元组(tuple)

不可变,有序

# 初始化
t = tuple([1,2])
tt = (1,2)
ttt = (1,)

数值运算

运算符 说明 运算符 说明
+ 加,用于数值类型进行加法运算,字符串类型用于拼接 ** 指数
- // 整除运算符,只保留整数部分
* 乘,字符串str与整型n之间使用表示,重复str获取n次并拼接 % 取余
/ == 、!= 、 >、 < 、>= 、<= 比较运算符
& 按位与,两者都为1才是1 ^ 异或,两者相等结果为0,不等为1
按位或,一个为1,就是1 ~
>> 向右移动若干二进制位 << 向左移动若干二进制位
and 逻辑与,所有参与运算的表达式都为True才为True or 逻辑或,所有参与运算的表达式有一个True就为True
is 判断两个变量是否为同一对象 not 使表达式产生相反的bool值
in 判断类型是否包含某个成员 表达式1 if 条件 else 表达式2 类似三目运算符
# 随机数
from random import randrange,randint,choice,random,sample,shuffle
randrange(start,stop=None,step=1) # 生成含头不含尾的随机数
randint(start,stop=None,step=1) # 生成含头含尾的随机数
choice((1,2,4) # 从序列中随机取出一个元素
random() # 生成一个0~1的随机数
sample((1,2,3,4,5)) # 从序列中随机取出多个元素组成一个新的序列
shuffle([1,2,3,4]) # 打乱列表中的元素

# 数学函数
from math import floor,ceil,round,abs
ceil(11.1) # 12 向上取整
floor(11.1) # 11 向下取整
''' 
四舍六入,当尾数小于5,直接舍去,当尾数大于5,前一位进1,当尾数等于5
且5之后的任意数位都为0,若前一位是偶数就直接舍去,否则进1,5之后的任意数位不为0
就会舍去尾数,且前一位进1
'''
round(1.86501) # 1.87 
abs(-1) # 1 绝对值
'''
排序
iterable表示要进行排序的序列
key可以引用一个函数,通过此函数可以返回自定义的用于排序的值
reverse表示是否将排序好的值进行翻转,默认为False
'''
sorted(iterable,key,reverse) # sorted(['a','werw','yd'],key=len) 返回['a','yd','werw']

流程控制

# 多分支 
if 条件1:
    符合条件1的代码
elif 条件2:  # 可以有多个
    符合条件2的代码
else:
    不符合12的代码

# 单分支
if 条件1:
    符合条件1的代码

# 双分支
if 条件1:
    符合条件1的代码
else:
    不符合12的代码


while 判断条件:
    代码块

for 变量列表 in 迭代器对象:
    代码块
# for常与range函数一起使用,range可以产生一组有序的整数序列
range(start,end,step) # range(2,8,2) 输出 2、4、6
# 循环代码中break跳出循环,continue跳过本次循环执行下一次循环

文件操作

# os 操作系统模块
os.getcwd() # 获取当前文件路径
os.listdir() # 获取当前目录下的所有文件,并将其写入list
os.mkdir('tmp') # 创建一层目录,一般采用相对路径
os.rmdir('tmp') # 删除空目录,采用相对路径
os.makedirs('/tmp/test') # 创建多级目录
os.removediirs('/tmp/test') # 删除嵌套目录
  • mode参数

    • 字符 描述
      r 读取,不指定mode参数时默认为r
      w 写入文件,写入前会清空文件
      x 创建一个新的文件并允许写入
      a 将数据追加到文件末尾,不会清空文件
      b 以二进制形式读写文件
      t 以文本方式读写文件
      + 打开一个文件进行读取和写入
  • # 打开文件从而进行读写操作
    '''
    :param file:指定要进行操作的文件名
    :param encoding:指定编码格式,只用于文本模式
    :param buffering:指定缓冲区大小
    :param newline:指定如何处理换行符,只用于文本模式,有效值:None、空字符串、\r,\n.\r\n
    :param errors:指定如何处理编码错误
    '''
    with open(file,mode='r',buffering=-1,encoding=None,errors=None,
        newline=None,closefd=True,opener=None) as f:
        f.read() # 读取,读取全部内容到内存中
        f.readline() # 逐行读取
        f.readlines([size]) # 以列表形式读取size行,若未指定则读取所有行
        for l in f: # 通过迭代器获取行
            print(l)
        f.write('zhangsan') # 写入
        f.tell() # 获取当前文件指针的位置
        f.seek(偏移量,起始位置) # 偏移量,单位字节,起始位置:0文件头,默认、1,当前位置、2,文件尾部
        f.close() # 关闭文件
    
    import io
    s = io.StringIO() # 读写文本文件
    b = io.BytesIO() # 读写二进制文件
       
    

函数

# 函数的定义
def 函数名(参数列表):
    函数体 

# 函数调用
函数名(参数)

def f(a):
    """
    函数的文档:定义在函数体内的第一个多行注释
    :param a
    :return
    """
f.__doc__ # 获取注释内容

# a表示位置参数,b表示关键字参数
# 向函数传递参数时,先传递位置参数再传关键字参数
def fn(a,b=None):
    pass
# 参数列表中出现*,表示此字符之后的参数都必须按关键字传递参数值
# 参数列表中出现/,表示此字符之前的参数都必须按位置传递参数值
  • 可变参数(可以传递0或多个参数)

    • *args:表示位置参数

    • **args:表示关键字参数

    • def f(*args,**xargs):
          print(args) # 返回元组
          print(xargs) # 返回字典
      # 若可变的位置参数后出现非可变参数,在调用函数时,可变参数后的非可变参数必须按照关键字函数传递
      def fn(*args,d):
          pass
      fn(1,2,d=3)
      
  • 函数传递

    • 将函数对象作为参数传递时,不需要带小括号,因为只需要传递函数对象的引用

      • def f1(f):
            pass
        def f2():
            pass
        f1(f2)
        
    • 装饰器

      • 装饰器是一个返回值是函数的函数

      • def f(*args):
            def ff():
                print('hahah')
            return ff
        
        @f
        def fff():
            print('666')
        
        fff() # hahah
        
        # 闭包
        def f1():
            def f2():
                print('closer')
            return f2
        
        # 调用f2
        f1()()
        
      • 内置装饰器

        @property # 可以不用添加括号调用方法
        @staticmethod # 与self解绑可以直接使用类名调用方法
        @classmethod # 传递类本身
        
  • 匿名函数

    • 使用lambda关键字创建,不使用return,表达式的值作为返回值,只能写一行

    • print(lambda x:print(x),1),输出1

面向对象

# 创建
class <类名>(基类列表):
    <类代码>

class people:
    # 在类型被案例化的过程中会调用__init__,__new__方法,多数情况只需要定义__init__方法即可    # 创建对象案例,cls表示要案例化的类型,一般是当前类型
    def __new__(cls): # 先调用
        # 必须返回对象案例,一般以下述方式产生对象案例
        return object.__new__(cls)
    # 设置一些属性的初始值
    def __init__(self): # 之后调用
        pass
p = people() # 类的案例化

 # 带参数的构造函数
class animal:
    # 可以使用可变参数,这样无论__init__的参数如何变动也不会影响到__new__ 
    def __new__(cls,*args,**kwargs):    
        return object.__new__(cls) # object.__new__(cls)只接收一个参数
    # 若同时定义__new__,__init__,就需要保证两个方法的参数一致,因为在案例化时参数
    # 会先传递给__new__再传递给__init__,当两个方法接收的参数不一致时会报错
    def __init__(self,color): 
        self.color = color
a = animal('red') # 传递参数,self不需要显式传递
方法
class demo:
    # 案例方法,显式参数传递从第二个参数开始
    def get_value(self,key):
        pass
    # 类方法,调用时直接使用类型引用,无须创建类型案例
    @classmethod
    def get_age(cls,name):
        pass
    # 静态方法,与类型和案例都无关,不需要隐式定义第一个参数
    @staticmethod
    def add(a,b):
        pass
# 案例方法调用
d = demo()
d.get_value('age')
# 类方法调用
demo.get_age('zhangsan')
# 静态方法调用
demo.add(1,2)
继承与多态
# 继承:当子类从父类继承后,即拥有父类的功能,也拥有子类自己的功能
# 子类中的方法与父类中的方法重名,会覆盖父类方法
# 父类(基类)
class father:
    def run(self):
        print('f.run')
# 子类(派生类),子类可以继承多个父类
class son(father):
    def run(self):
        print('s.run')
        father.run(self) # 调用父类的run方法
        super().run() # 调用父类的run方法,第二种方式
s = son()
s.run() # 输出s.run f.run

# 多态:一种事物具备多种形态
class Animal:
    def run(self):
        print(f'{type(self).__name__}对象')

class Tiger(Animal):
    pass
class Lion(Animal):
    pass
Tiger().run()
Lion().run()

# 检查一个类是否为另一个类的子类
# 参数1是待检查的类
# 参数2可以时一个类,或多个类组成的元组对象
# 当参数2为元组时,其中的类只要有一个是参数1的父类就会返回True
issubclass(cls,cls_or_tuple)
father.__subclasses__() # 获取father类的直接子类

# 初始化派生类型
# 当一个类派生出另一个类时,__init_subclass__方法就会被调用
class person:
    # 主要是对派生类进行初始化
    def __init_subclass__(cls,**kwargs):
        if kwargs:
            for k,v in kwargs.items():
                setattr(cls, k, v)
class doctor(person,name='zhangsan',age=18):
    pass
for k,v in vars(doctor).items():
    if not k.startswith('__'):
        print(f'{k}:{v}')

对象复制

# id返回对象的唯一标识,若两个变量的标识相同,表明的是引用的同意对象
id(a) == id(b) # 判断两个变量是否引用同一对象
id(a) is id(b) # 同上
# 浅拷贝仅复制对象本身,不会复制对象引用的其他对象 copy()
# 深拷贝不仅复制对象本身,也会递归式的复制对象中引用的其他对象 deepcopy()

# dir()函数可以获取一个列表案例,存放了此对象的成员名称
# __sizeof__方法返回案列占用的内存大小,字节为单位
# __str__将对象转换为字符串,一般返回的字符串比较简短,对象传递给str()时被调用
# __repr__将对象转换为字符串,返回的字符串可以作为python代码执行,对象传递给repr()函数时,被调用
上下文管理
# with可以创建一个封闭的上下文空间,代码所访问的资源仅在此范围内有效,当代码离开with语句块之后就会释放资源
with 资源1,资源2,...: # 语法
    代码
with open('a.txt',mode='r') as f: # as创建别名
    pass 

# 自定义类型支持上下文管理,需实现以下两个方法
'''
__enter__:进入上下文范围内调用此方法,若在with中不需要访问任何案例就返回False,
若需要访问某个案例就返回True
'''
'''
 __exit__:退出上下文范围调用。方法接收三个异常相关参数
(异常的类型、异常案例的引用以及traceback对象),若在上下文中引发异常,
异常信息会传递给这三个参数,若为发现异常,三个参数都为None。当上下文中引发异常并且此方法
返回None或False时,异常会被再次抛出并终止程序,若返回True,异常不再抛出
'''

异常

# 捕获异常
try:
    # 可能发生异常的代码
except Exception as e: # 若省略except就必须包含finally子句,这时发生异常时会忽略异常
    # 发生异常后处理的代码
finally:
    # 可选,不论try后边的代码是否引发异常,该子句都会执行,常用与清理代码(如释放文件资源等)

# 抛出指定的异常
raise Exception("foo occurred")
raise RuntimeError from NameError # 从NameError引发RuntimeError

# 自定义异常,派生自exception类
class CustomException(Exception):
    def __init__(self,*args,msg=None):
        # 调用基类的构造函数
        super().__init__(*args)
        # 设置错误信息
        self.msg = msg

模块

将功能相近的函数放到一个文件中,一个py文件就是一个模块,模块名就是文件名去掉后缀

好处:提高代码可复用、可维护性

  • 导入模块

    • import 模块名 as 别名:导入所有成员,并设置别名

    • from 模块名 import 要导入的成员列表:导入部分成员,可以导出单个或多个,成员之间用逗号隔开

      • *代表导入所有
        • 若模块中设置__all__[]变量,将导入该变量中所列出的成员
        • 若未设置,会导入除下划线开头的所有成员
    • 上述两种形式都会将模块中的内容加载,若不想其调用,可以在模块内部使用__name__限制模块内的调用,在自己模块中__name__的输出是__main__,否则返回模块的实际名称

    • python -m 模块名:运行模块

      # 获取当前模块中的所有成员名称
      from module import *
      dic = globals().copy() # globals返回当前模块中的所有成员名称
      for i in dic.keys():
      print(i)
      
  • 动态生成__all__变量,排除以_和py开头的成员

    • __all__ = [n for n in globals() if n[0] != '_' and n[:2] != 'py' ]

当目录下存在__init__.py文件时,该文件可以不写任何代码,只要存在就会视其所在目录为包

  • 当包作为模块被直接运行时,需要在作为包的目录下添加一个__main__.py文件

    import packages # 导入包
    import packages.demo # 导入指定的子模块
    from packages.demo import set # 导入子模块中的指定成员
    # 合并子模块的成员列表
    # 在__init__.py中导入模块的成员
    from .demo1 import _set,age # .表示当前目录下的模块,..代表当前目录的父级目录中的mod模块
    from .demo2 import _get,name
    

属性

  • 属性系统支持动态操作,所以即使一个空白类,也可以进行属性读写

    • # 空白类
      class demo():
          pass
      d = demo() # 创建案例
      d.age = 18 # 添加属性
      # setattr(obj,name,value)
      setattr(d,'name','zhangsan') # 添加属性
      print(d.age) # 获取属性 18
      # getattr(obj,name[,default])获取不存在且未设置默认值的属性会报错
      print(getattr(d,'name')) # 获取属性 zhangsan
      # __dict__用于存储对象的属性,是一个字典集合,可以直接访问它进行读写属性
      print(d.__dict__) # {'age': 18,'name':'zhangsan'}
      print(d.gender) # 属性不存在发生AttributeError错误
      del d.age # 删除属性,属性被删除后就不能在进行访问
      # delattr(obj,name) 
      delattr(d,'name') # 删除属性
      # hasattr(obj,name)
      hasattr(d,'age') # False 判断属性是否存在
      
  • __slots__

    • 派生类需要重新定义__slots__成员

    • 为类型本身设置属性,且在__slots__中存在该属性,那么该属性对于类型案例就是只读的

    • # 在定义类型时,指定__slots__成员,类型案例就不能再创建__dict__成员
      # 只约束案列不约束类型本身
      class people:
          __slots__ = 'age','name','gender'
          # age = 18 # 报错,类变量与__slots__成员冲突
          # 解决,在__init__中设置,因为__init__在案例创建之后调用
          def __init__(self):
              self.age = 20 
      p = people()
      p.age = 18
      p.name = 'zhangsan'
      p.classes = 'male' # 报错,没有gender属性
      people.gender = 'male' # 可以设置
      p.gender = 'women' # 报错,只读属性
      
  • 自定义属性访问

    • __getattribute__方法,当案例属性被访问时调用(不论被访问的属性是否存在都会被调用)

    • __getattr__:只在被访问的属性不存在时调用

    • __setattr__:设置属性时调用(不论被访问的属性是否存在都会被调用)

    • __delattr__:当案例属性被删除时调用

  • 描述符

    • 作用:对属性值进行封装,使用描述符时,描述符的案例要存储在当前案例的父级对象的变量字典中

    • 一个类被识别为描述符的条件,即是否存在下列方法

      • __get__:获取属性值时调用

      • __set__:设置属性值时调用

      • __delete__:属性被删除时调用

      • __set_name__:当描述符被案例化并赋值给某个属性时调用

    • property(fget=None,fset=None,fdel=None,doc=None)也可以封装属性值文章来源地址https://www.toymoban.com/news/detail-795483.html

异步

from threading import Thread,Lock
# 多线程
'''
:param group: 保留参数,暂不使用
:param deamon: 指定新创建的线程是否为守护线程,该线程一般在后台运行
:param args/kwargs:传递给target参数所引用的函数,若函数无参数,可以忽略 
:param target: 引用一个函数,在函数中编写需要在新线程中运行的代码,线程启动时调用
:param name: 指定新线程的名称,一般忽略
'''
# 创建线程
t = Thread(group=None,target=None,name=None,args=(),kwargs=None,*,daemon=None
# 启动线程
t.start() # 一个线程案例的生命周期中只能调用一次
# 由于子线程时异步执行的,主线程不会等待其执行完成,若希望主线程等待子线程执行完成,调用join方法
t.join() # 等待子线程执行完毕
# 多个线程访问同一个资源时就需要加锁
from threading import Thread, Lock
from time import sleep
num = 10
lock = Lock()
def work():
    global num  # 全局变量
    while True:
        # 方式1
        # if lock.acquire():  # 加锁
        #     if num > 0:
        #         sleep(0.1)
        #         num -= 1
        #         print(f'剩余:{num}')
        #     lock.release()  # 解锁
        # 方式2
        with lock:
            if num > 0:
                sleep(0.1)
                num -= 1
                print(f'剩余:{num}')

threads = [Thread(target=work) for i in range(3)]  # 创建3个子线程
for i in threads:
    i.start()  # 启动子线程

# 等待事件信号,Event,事件对象可以在不同线程之间访问,调用wait方法会被阻塞,直到事件对象的set方法被调用
from threading import Thread,Event
e1 = Event()
e2 = Event()
def one():
    print("downloading one:",end='')
    for i in range(5):
        sleep(0.1)
        print('#',end='')
    print('done')
    e1.set() # 完成发送信号
def two():
    e1.wait() # 等待信号
    print("downloading two:", end='')
    for i in range(5):
        sleep(0.1)
        print('#', end='')
    print('done')
    e2.set()
def install():
    e2.wait()
    print("installing...")
    sleep(1)
    print('success')
t1 = Thread(target=one)
t2 = Thread(target=two)
t3 = Thread(target=install)
t1.start()
t2.start()
t3.start()
'''
downloading one:#####done
downloading two:#####done
installing...
success
'''

# 异步,若函数内部调用了异步函数,那么该函数也要用async关键字定义
async def fn(): # 定义
    pass
await fn() # 调用

网络

# TCP服务端通信流程
# 创建Socket对象
import socket
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM,socket.IPPROTO_TCP)
# 绑定地址和接口
s.bind(('127.0.0.1', 8888))
# 监听客户端连接请求
s.listen()
# 接收客户端的连接,产生一个新的Socket对象,此对象专门用于与客户端进行通信
cli,addr = s.accept() # cli与客户端进行通信,addr包含客户端的地址和端口
# 向客户端发送信息或接收来自客户端的信息
while True:
    data = cli.recv(1024) # recv读取来自客户端的数据,并设置缓冲区大小为1024字节
    if not data:
        break
    print(f'客户端消息:{bytes(data).decode()}')
# 关闭Socket,释放资源
cli.close()
s.close()

# TCP客户端通信流程
# 创建Socket对象
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM, socket.IPPROTO_TCP)
# 连接服务器
s.connect(('127.0.0.1',8888))
# 连接成功,发送或接收数据
s.send('hi'.encode())
# 释放资源
s.close()

# UDP服务端
# 创建Socket对象
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
# 调用bind绑定url
s.bind(('127.0.0.1', 9999))
# 调用recvfrom方法接收
while True:
    data, cli = s.recvfrom(1024)
    if not data:
        print("no data")
        break
    print(f'接收来自{cli[0]}:{cli[1]}的消息:{data.decode()}')
# 释放资源
s.close()

# UDP客户端
# 创建Socket对象
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
# 调用sendto方法向服务器发送数据
while True:
    data = input('输入消息: ')
    if not data:
        print("no data")
        break
    s.sendto(data.encode(),('127.0.0.1', 9999))
# 释放资源
s.close()

到了这里,关于python 入门基础 Introduction to Python Fundamentals的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【python零基础入门学习】python基础篇(一)

    官方: www.python.org,自行安装,linux上有自带python,win自行安装。 [student@room9pc01 05]$ python --version Python 2.7.5  #创建虚拟环境: [root@room9pc01 bin]# pwd /root/nsd1907/bin [root@room9pc01 bin]# ls activate  activate.csh  activate.fish  easy_install  easy_install-3.6  pip  pip3  pip3.6  python  python3 [root@room9p

    2024年02月11日
    浏览(39)
  • 【Python入门】Python基础语法

    前言 📕作者简介: 热爱跑步的恒川 ,致力于C/C++、Java、Python等多编程语言,热爱跑步,喜爱音乐的一位博主。 📗本文收录于Python零基础入门系列,本专栏主要内容为Python基础语法、判断、循环语句、函数、函数进阶、数据容器、文件操作、异常模块与包、数据可视化等,

    2024年02月03日
    浏览(80)
  • Python零基础入门(一)——Python简介与基础语法

    个人简介:机电专业在读研究生,CSDN内容合伙人,博主个人首页 Python入门专栏:《Python入门》欢迎阅读,一起进步!🌟🌟🌟 码字不易,如果觉得文章不错或能帮助到你学习,可以点赞👍收藏📁评论📒+关注哦!😊😊😊 Python是一门适合初学者入门的编程语言,本文将介

    2024年02月10日
    浏览(40)
  • Python入门教程 | Python 基础语法

    第一个字符必须是字母表中字母或下划线 _ 。 标识符的其他的部分由字母、数字和下划线组成。 标识符对大小写敏感。 在 Python 3中,可以用中文作为变量名,非 ASCII 标识符也是允许的了。默认情况下,Python 3 源码文件以 UTF-8 编码,所有字符串都是 unicode 字符串。 在Python中

    2024年02月11日
    浏览(56)
  • 【Python 零基础入门】基础语法

    当我们学习一门新语言, 首先要熟悉它的语法规则. 这就如同学习一门外语, 我们需要知道句子的结构, 词汇的使用和语法的规则. 与 Java 中的 “{}” 不同, Python 使用缩进. 缩进在 Python 中非常重要, 定义了代码的结构和层次. 通常用 4 个空格作为标准的缩进 (TAP 键). 在我们编写代

    2024年02月04日
    浏览(41)
  • Introduction to GraphQL-style APIs

    GraphQL is an open-source query language and runtime environment developed by Facebook for constructing APIs. Unlike traditional RESTful APIs, GraphQL allows clients to send precise queries to retrieve the necessary data without returning extraneous information. The core idea of GraphQL is to allow clients to define the data structure they require, rather th

    2024年02月20日
    浏览(40)
  • Introduction to Unit Testing in Java

    作者:禅与计算机程序设计艺术 UNIT TESTING (UNIT测试),是在软件开发生命周期中不可或缺的一环。单元测试是一个模块化的测试工作,它的目标是验证某个函数、模块或者类的某个功能是否符合设计要求。它通过对代码中独立的测试用例进行运行和验证,发现错误并报告给相

    2024年02月08日
    浏览(48)
  • 【Python】从入门到上头—Python基础(2)

    默认情况下,Python 3 源码文件以 UTF-8 编码,所有字符串都是 unicode 字符串。 当然你也可以为源码文件指定不同的编码: 首字母必须是字母表中 字母或下划线 _ 。 标识符的其他的部分由 字母、数字和下划线 组成。 标识符对大小写敏感。 在 Python 3 中,可以用中文作为变量名

    2024年02月11日
    浏览(30)
  • 【Python学习篇】Python基础入门学习——你好Python(一)

     个人名片: 🦁作者简介:学生 🐯个人主页:妄北y 🐧个人QQ:2061314755 🐻个人邮箱:2061314755@qq.com 🦉个人WeChat:Vir2021GKBS 🐼 本文由妄北y原创,首发CSDN 🎊🎊🎊 🐨座右铭:大多数人想要改造这个世界,但却罕有人想改造自己。 专栏导航: 妄北y系列专栏导航:   C/C++的

    2024年03月09日
    浏览(55)
  • 【零基础入门学习Python---Python函数和模块】

    🚀 Python 🚀 🌲 算法刷题专栏 | 面试必备算法 | 面试高频算法 🍀 🌲 越难的东西,越要努力坚持,因为它具有很高的价值,算法就是这样✨ 🌲 作者简介:硕风和炜,CSDN-Java领域优质创作者🏆,保研|国家奖学金|高中学习JAVA|大学完善JAVA开发技术栈|面试刷题|面经八股文|经验

    2024年02月11日
    浏览(43)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包