Python Random(随机)原理解析与编程实践

本文涉及的产品
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
云解析 DNS,旗舰版 1个月
全局流量管理 GTM,标准版 1个月
简介: 本文介绍Python Random(随机)原理解析与编程实践

Python基础专题 - Random(随机)详解


李俊才 的个人博客

已入驻阿里云博客

邮箱 :291148484@163.com

本文地址https://blog.csdn.net/qq_28550263/article/details/115441596

继续阅读文本前,先说一个难以回避的事实:

随机远远不是一个单纯的统计学概念,它是一个让物理学家都讨论不休、目前一切结论都可能存在历史局限性的谜。

随机的背后依赖于不确定性,目前支撑起随机存在的主要是当下量子力学中的相关理论并且在当前的实践中似乎是对的。

可以参考一些网络上的词条以及文章:

【上帝不会掷骰子】【真随机】【中国科学家在国际上首次实现器件无关的量子随机数】


目 录

1、什么是随机

2、使用Python内建random伪随机数模块

3. Numpy伪随机数模块numpy.random

附录:常用数学分布介绍


1、什么是随机

1.1 随机可能是造物者的杰作

随机其实并不是一个像其表面那样容易理解的问题,但我们可以这样来描述随机:

对于一个取值有限的事件

  • 从上帝视角看,在事件真是发生前没有任何理由认为其中任何一个事件更可能会真实发生,那么认为这个事件是随机事件;
  • 从实践视角看,不论实践主体做任意多次独立重复实验,事件中任意一个取值(样本点)实际发生的频率随着重复实验的次数的无限增多,各个取值实际发生的次数无限接近于完全相等

然而不得不说,世界纷繁复杂,取值有限的事件无非是我们对这个无限广袤世界从某一角度高度抽象和离散化的结果。

如果将人类认知规律分为必然规律和统计规律,必然规律指事物本质的规律,它毫无例外地适用于事物所有个体。而统计规律是指通过对随机现象的大量观察后所呈现出来的事物的集体性规律

这里所谓上帝指得是拥有一个假想中的超能力以至于能够在事件发生前可以实践出无限种结果的主体。人类不是上帝,不能真实拥有上帝视角,因此所谓随机正是一种通过统计认知的规律。

1.2 伪随机、随机种子与计算机编程中的随机

随机不是人为制造的,而是根生于物理世界。人们不可以通过一种算法凭空创造不确定性

所谓【伪随机】是用确定性的算法计算出的一种在[0,1][0,1]上产生均匀分布的随机数序列的算法,它并不真正的随机,它需要一个随机种子为它提供随机性的动力之源。

随机种子本质就是一个作为初始条件的真随机数,一般通过其查询随机数表后再经过一定计算获得计算机编程中的随机数。

系统是如何获得随机种子呢?

生成伪随机数需要随机种子很多时候计算机系统维护了一个熵池,不断收集非确定性的硬件事件,如机器运行环境中产生的硬件噪音,在运行时刻某一瞬间的系统时间尾数等等,以此生成随机种子。

计算机编程里生成的随机数都是伪随机数,但在一般统计意义上看我们仍然可以视为真随机数。


2、使用Python内建random伪随机数模块

2.1 随机性设定

Python中有内建模块random可以用来生成[0.0,1.0)上的精度为53位的伪随机数,该模块使用马特赛特旋转演算法(MersenneTwister)实现了各种分布的伪随机数生成器。

>MersenneTwister算法中,一个n位的`线性反馈移位寄存器(LFSR)`能够在重复之前产生 $2^n-1$ 位长的**伪随机序列**,称之为m序列,将产生的伪随机序列除以序列的周期,就可以得到(0,1)上均匀分布的`伪随机序列`了。

  • random.getstate() - 返回捕获生成器当前内部状态的对象。
importrandomstate=random.getstate()
  • random.setstate(state) - 将生成器的内部状态恢复到state的状态,一般由getstate()先获取state。
importrandomrandom.setstate(state)

该模块中,可以使用random.seed(a=None, version=2)方法指定a的指为一个确定数在编程时固定随机种子,这样在多次运行生成随机数的代码时,你会发现"随机"出来的结果是同一个。如果 a 被省略或为 None ,则使用当前系统时间。在上一节 (1.2节) 中对于内部机制有详细介绍,这里不在论述。

2.2 实用方法

(1)生成[0,1)上的随机浮点数

importrandomrandom.random()

(2)生成[a,b][a,b)上一个随机浮点数(区间可以不是整数)

  • - 当 $a <= b$ 时, $a <= N <= b$ ;

- 当 $b < a$ 时, $b <= N <= a$.

- 取决于等式 $a + (b-a) * random()$ 中的浮点舍入,终点 b 可以包括或不包括在该范围内。

importrandomrandom.uniform(2, 3)

(3)生成[a,b]上的随机整数

random.randint(a, b)
importrandomrandom.randint(0, 9) # 生成[0,9]上的随机整数

(4)在区间[start, stop]上以间隔step生成随机整数

random.randrange(start, stop[, step])
importrandomrandom.randrange(1, 9[, 2])

(5)按高斯分布(正态分布)生成随机数

random.gauss(mu, sigma)

mu 是平均值,sigma 是标准差

importrandomrandom.gauss(mu, sigma)

(6)按β分布生成[0,1]上的随机数

random.betavariate(alpha, beta)

参数的条件是 alpha > 0 和 beta > 0。 返回值的范围介于 0 和 1 之间。

importrandomrandom.gauss(1, 3)

(7)用作选择器:从序列中随机选取一个元素

random.choice(seq)
random.choices(population, weights=None, *, cum_weights=None, k=1)
  • random.choice(seq):从非空序列 seq 返回一个随机元素。其中 seq 可以是包括列表、元组、range序列,甚至字符串在内的任意Python序列类型。如果 seq 为空,则引发 IndexError。
importrandomrandom.choice(["我","爱","学","习","Python","编","程"])
random.choice("今天天气不错")
  • random.choices(population, weights=None, *, cum_weights=None, k=1):从population中选择替换,返回大小为 k 的元素列表。 如果 population 为空,则引发 IndexError。
  • 如果指定了 weight 序列,则根据相对权重进行选择;
  • 如果给出 cum_weights 序列,则根据累积权重(可能使用 itertools.accumulate() 计算)进行选择;
  • 如果既未指定 weight 也未指定 cum_weights ,则以相等的概率进行选择;
  • weights 或 cum_weights 可以使用任何与 random() 返回的 float 值互操作的数值类型(包括整数,浮点数和分数但不包括十进制小数)

(8)随机打乱序列元素位置(序列洗牌函数)

random.shuffle(x[, random])

将序列 x 随机打乱位置。

  • 可选参数 random 是一个0参数函数,在 [0.0, 1.0) 中返回随机浮点数;
  • 默认情况下,这是函数 random()
importrandomx= ["我","爱","学","习","Python","编","程"]
random.shuffle(x)
x
  • Out[R]:[‘程’, ‘编’, ‘我’, ‘习’, ‘Python’, ‘学’, ‘爱’]

(9)无重复随机抽样

random.sample(population, k, *, counts=None)

通过无重复随机抽样返回包含来自总体的元素的新列表,同时保持原始总体不变。

  • population: 集合或者序列,为样本总体的容器;
  • k: int,抽取的子序列的长度(元素个数);
  • counts:list,元素为重复样本的权重,即该样本的出现次数。counts中的元素与population的元素一一对应。
    【代码1】
importrandompopulation= ['王', '者','荣','耀']
random.sample(population,counts=[4, 3, 2, 1], k=3)
  • 和下面的代码时等效的:
    【代码2】
importrandompopulation= ['王', '王', '王', '王', '者', '者', '者', '荣', '荣', '耀']
random.sample(population,counts=[4, 3, 2, 1], k=3)

这里无重复随机抽样中的无重复不是说返回的元素不能有一样的,而是指用的是五放回抽样。

3. Numpy伪随机数模块numpy.random

3.1 numpy中的随机生成器

3.1.1 [简单了解]Permuted Congruential Generator(PCG)

该算法更详细内容可以参考https://www.pcg-random.org/

Permuted Congruential Generator(PCG)即所谓置换同余生成器,是用于随机数生成的一系列简单、快速、节省空间的,统计上良好的算法。在Python编程中,生成器是一种特殊的函数。生成器与普通函数不同的是,它返回迭代器的函数,只能用于迭代操作。生成器(generator)的应用往往解决了存储空间不足的问题,无需再程序以开始就完整计算整个值。

从RandomState类到Generator类

在之前,Numpy.random模块与Python内建的random等模块类似,直接使用马特赛特旋转演算法(Mersenne Twister)伪随机数生成器的容器,并提供有RandomState类:

numpy.random.RandomState(seed=None)

由于该类不是最好的选择,其用法仅以伪代码简要介绍如下:

fromnumpy.randomimportMT19937fromnumpy.randomimportRandomStaters1=RandomState(12345)          # 获取seed=12345的RandomState()实例 rsmt19937=MT19937()              # 旧版MT19937 BitGeneratormt19937.state=rs.get_state()   # get_state()方法返回一个表示生成器内部状态的元组。rs2=RandomState(mt19937)       # 获取seed为mt19937状态的RandomState()实例 rs2 # 随机返回数值rs1.random()
rs2.random()
# 按照标准正态分布随机返回数值rs1.standard_normal()
rs2.standard_normal()
# 按照指数分布随机返回数值rs1.standard_exponential()
rs2.standard_exponential()
# 以上是控制可获取随机状态,即rs1和rs2都传入了seed参数。# 不传参数时才能随机中获取不一样的值(见之前关于计算机随机的介绍)。# 要使用随机性,可以参考下面的做法rs=RandomState()
rs.random()                  # 从[0.0,1.0)上随机抽取浮点数样本rs.rand(d0, d1, , dn)       # 从标准正态分布中返回一个或多个样本。rs.normal([loc, scale, size])# 从正态(高斯)分布中抽取随机样本rs.standard_normal()         # 从标准正态(高斯)分布中抽取随机样本rs .standard_exponential()   # 从标准指数分布中随机抽取样本rs.shuffle(X)                # 对X进行洗牌,即随机打乱顺序。X是一个序列,如列表。rs.beta(a, b[, size])        # 从Beta分布中随机抽取样本binomial(n, p[, size])       # 从二项分布中随机抽取样本chisquare(df[, size])        # 从卡方分布中抽取样本rs.dirichlet(alpha[, size])  # 从Dirichlet分布中抽取样本rs.f(dfnum, dfden[, size])   # 从F分布中抽取样本rs.gamma(shape[, scale, size])                  # 从Gamma分布中抽取样本rs.geometric(p[, size])                         # 从几何分布中抽取样本rs.gumbel([loc, scale, size])                   # 从Gumbel分布中抽取样本rs.hypergeometric(ngood, nbad, nsample[, size]) # 从超几何分布中抽取样本

然而根据最新的Numpy 1.20.1文档,numpy.random.Generator(bit_generator)(以下简称Generator类)是上述numpy.random.RandomState(seed=None)(以下简称RandomState类)的替代品。

numpy.random.Generator(bit_generator)
  • Generator类依赖于附加的BitGenerator来管理状态并生成随机位,然后将这些随机位从有用的分布转换为随机值。所使用的默认BitGenerator Generator为PCG64。可以通过将实例化的BitGenerator传递给来更改BitGenerator Generator。numpy.random.default_rng()方法能够使用默认的BitGenerator(PCG64)构造一个新的Generator,用法示例如:
from numpy.random import default_rng
rng = default_rng(12345)     # 构造一个随机数生成器类rng
rng.random()                 # 从[0.0,1.0)上随机抽取浮点数样本
  • Out[]:0.22733602246716966
    或者你不必指定随机种子,以让每次运行时随机获取一个不同的值:
from numpy.random import default_rng
rng = default_rng()          # 构造一个随机数生成器类rng
rng.random()                 # 从[0.0,1.0)上随机抽取浮点数样本
  • Out[R]:0.642785685979066
  • 新的numpy.random.BitGenerator(seed=None) 类 是Numpy中通用BitGenerator的基类,所使用的默认BitGenerator Generator为PCG 64。PCG-64是 O’Neill 置换同余生成器 的128位实现。PCG64状态向量由2个无符号128位值组成,这些值在外部表示为Python ints
  • 可以用numpy.random.PCG64(seed=None)类生成一个新的BitGenerator,用法大致如下:
fromnumpy.randomimport (
Generator, 
PCG64, 
SeedSequence)
sg=SeedSequence(1234)                                  # 获取熵值(熵在信息理论中反应不确定度,实际中有系统收集,见上文)rg= [Generator(PCG64(s)) forsinsg.spawn(10)]         # 使用这些值生成新的BitGenerator

3.1.2 [重要]Generator(bit_generator)类的进一步讲解

前一节已经讲了,default_rng()函数是推荐使用的Generator生成器,并示例了生成一个随机数的写法。本节中将介绍更多常用的方法。

以下是展示用法的伪代码

fromnumpy.randomimportdefault_rngrng=default_rng()          # 构造一个随机数生成器类rngrng.integers(low[, high, size, dtype, endpoint])        # 从返回随机整数low(含)到high(不含),# 或者如果endpoint=True,low(含)到 high(含)rng.random([size, dtype, out])                          # 返回[0.0,1.0)上的一个随机浮点随rng.choice(a[, size, replace, p, axis, shuffle])        # 随机选择样本rng.bytes(length)                                       # 返回随机字节,length为字节长度rng.shuffle(x[, axis])              # 序列洗牌(随机打乱顺序)rng.permutation(x[, axis])          # 随机排列序列,或返回排列范围rng.permuted(x[, axis, out])        # 随机置换X沿轴轴线rng.beta(a, b[, size])              # 从Beta分布中抽取样本rng.binomial(n, p[, size])          # 从二项分布中抽取样本rng.chisquare(df[, size])           # 从卡方分布中抽取样本rng.dirichlet(alpha[, size])        # 从Dirichlet分布中抽取样本rng.exponential([scale, size])      # 从指数分布中抽取样本rng.f(dfnum, dfden[, size])         # 从F分布中抽取样本rng.gamma(shape[, scale, size])     # 从Gamma分布中抽取样本rng.geometric(p[, size])            # 从几何分布中抽取样本rng.gumbel([loc, scale, size])      # 从Gumbel分布中抽取样本rng.hypergeometric(ngood, nbad, nsample[, size])        # 从超几何分布中抽取样本rng.laplace([loc, scale, size])           # 从具有指定位置(或均值)和比例(衰减)的# 拉普拉斯或双指数分布中抽取样本rng.logistic([loc, scale, size])          # 从逻辑分布中抽取样本rng.lognormal([mean, sigma, size])        # 从对数正态分布中抽取样本rng.logseries(p[, size])                  # 从对数级数分布中抽取样本rng.multinomial(n, pvals[, size])         # 从多项分布中抽取样本rng.multivariate_hypergeometric(colors, nsample)        # 从多元超几何分布生成变量rng.multivariate_normal(mean, cov[, size, ])           # 从多元正态分布中抽取随机样本rng.negative_binomial(n, p[, size])                     # 从负二项分布中抽取样本rng.noncentral_chisquare(df, nonc[, size])              # 从非中心卡方分布中抽取样本rng.noncentral_f(dfnum, dfden, nonc[, size])            # 从非中心F分布中抽取样本rng.normal([loc, scale, size])      # 从正态(高斯)分布中抽取随机样本rng.pareto(a[, size])               # 从具有指定形状的Pareto II或Lomax分布中抽取样本rng.poisson([lam, size])            # 从泊松分布中抽取样本rng.power(a[, size])                # 从具有正指数a-1的功率分布中以[0,1]抽取样本。rng.rayleigh([scale, size])         # 从瑞利(Rayleigh)分布中抽取样本rng.standard_cauchy([size])         # 从mode = 0的标准柯西分布中抽取样本。rng.standard_exponential([size, dtype, method, out])   # 从标准指数分布中抽取样本rng.standard_gamma(shape[, size, dtype, out])          # 从标准Gamma分布中抽取样本rng.standard_normal([size, dtype, out])                # 从标准正态分布(均值= 0,标准差 = 1)中抽取样本rng.standard_t(df[, size])                   # 从自由度为df的标准学生氏分布(t分布)中抽取样本rng.triangular(left, mode, right[, size])    # 从间隔上的三角形分布中抽取样本。[left, right]rng.uniform([low, high, size])         # 从均匀分布中抽取样本rng.vonmises(mu, kappa[, size])        # 从冯·米塞斯(von Mises)分布中抽取样本rng.wald(mean, scale[, size])          # 从Wald或高斯逆分布中抽取样本rng.weibull(a[, size])          # 从威布尔分布中抽取样本rng.zipf(a[, size])             # 从Zipf分布中抽取样本

以下精选了上面展示的部分方法进行示例

  • 【注意】后面代码公用此段,不再重复书写:
importnumpyasnpfromnumpy.randomimportdefault_rngrng=default_rng()

随机选择器

a=np.array([1,5,7,9,8,7,3,1,4,6])
rng.choice(a)

随机洗牌

array=np.arange(10)
rng.shuffle(array)
array

Out[R]:array([9, 8, 0, 3, 2, 1, 6, 7, 4, 5])

  • 也可以不是数组而仅仅是一般的Python序列:
sequence= ["你","的","头","发","还","好","吗"]
rng.shuffle(sequence)
sequence
  • Out[R]:[‘你’, ‘发’, ‘的’, ‘好’, ‘头’, ‘还’, ‘吗’]

从二项分布(即伯努利分布)中抽取样本

n, p=10, .5# 试验次数,每次试验的概率rng.binomial(n, p, 100) # 结果抛硬币10次,测试100次。

Out[R]:

array([5, 4, 5, 4, 4, 4, 4, 2, 6, 6, 6, 5, 7, 6, 7, 4, 6, 7, 7, 6, 9, 7,
       6, 6, 5, 6, 6, 5, 5, 5, 2, 3, 6, 3, 6, 5, 7, 4, 5, 5, 5, 8, 2, 6,
       6, 3, 4, 4, 9, 6, 7, 3, 8, 8, 7, 4, 4, 2, 5, 4, 3, 5, 5, 3, 6, 5,
       2, 4, 7, 3, 6, 5, 7, 6, 5, 6, 5, 5, 3, 5, 5, 1, 3, 5, 3, 6, 4, 5,
       6, 6, 4, 5, 5, 6, 2, 3, 7, 6, 5, 6], dtype=int64)

从高斯分布(正态分布)中抽取样本

mu, sigma = 0, 0.1         # 均值和标准差
rng.normal(mu, sigma, 10)  # 随机挑选10个样本

Out[R]:

array([-0.08977574, -0.04510079, -0.1347215 ,  0.055061  , -0.07062946,
        0.06331096,  0.11478359,  0.07054353,  0.29988904, -0.07591274])

从泊松分布中抽取样本

rng.poisson(5, 30)

Out[R]:

array([10,  5,  6,  0,  5,  8,  5,  8,  6,  3, 10,  6,  8,  4,  9,  4,  4,
        4,  1,  4,  6,  4, 11,  4,  4,  2,  2,  4,  4,  4], dtype=int64)

从F分布中抽取样本

dfnum=1.# 组间的自由度dfden=48.# 组内的自由度rng.f(dfnum, dfden, 100)

Out[R]:

array([1.93197989e-01, 1.24205423e+00, 4.00232880e-01, 4.85092358e-02,
       3.32931687e+00, 2.05889475e+00, 4.61348458e-01, 3.00949845e+00,
       3.90822633e+00, 2.23728556e+00, 9.34600481e-03, 5.15363963e-01,
       1.43485077e-01, 4.41028093e-01, 1.32146240e-01, 1.11471393e+00,
       1.03337187e+00, 2.30848196e-01, 4.07377166e-01, 2.05472096e-01,
       1.63826036e+00, 4.46181253e-01, 1.86498211e+00, 2.66618563e+00,
       1.08118560e+00, 4.48247556e-01, 9.43349767e-02, 1.76855083e+00,
       2.95544929e-03, 6.73061275e-01, 2.15134324e-01, 1.39935387e-01,
       1.01244134e+00, 5.53635434e-03, 8.99606895e-01, 2.66732309e-01,
       1.18154518e+00, 1.12718292e+00, 2.10690001e-01, 5.68640747e-01,
       9.89775122e-03, 4.65351259e-02, 2.16960435e+00, 1.22627946e+00,
       1.15816353e+00, 2.03245748e+00, 8.48710506e+00, 2.08246000e+00,
       1.93013549e+00, 1.09309756e-01, 8.01513824e-01, 1.65082925e-01,
       3.19968754e-01, 1.31481564e-02, 2.47961229e-01, 4.73627037e-03,
       2.81335155e-02, 9.91148164e-02, 4.86448293e-01, 4.40648125e+00,
       9.06591744e+00, 1.27533676e+00, 4.73046307e-02, 1.87428590e-01,
       4.35645568e-01, 3.03655416e-01, 1.33503179e+00, 4.69885038e-01,
       4.82723958e-01, 8.95961791e-01, 1.65418312e+00, 6.51444154e-04,
       1.15344115e-01, 1.39118341e-01, 1.51368685e-01, 5.23925653e+00,
       2.70342516e+00, 1.36388925e-01, 7.42148964e+00, 4.99751983e-02,
       7.12414489e-01, 1.04688667e+00, 4.33790508e-04, 7.12767650e-02,
       3.57984128e-01, 3.16070339e-02, 3.07002039e-01, 6.77355120e-03,
       1.09919251e-03, 4.41067472e-02, 1.82543358e+00, 2.52812298e-01,
       2.00608200e+00, 3.32439576e+00, 3.43718583e-01, 1.57335325e-01,
       6.16422855e-01, 4.06029886e-01, 1.51402319e-02, 1.17152107e+00])

从卡方分布中抽取样本

rng.chisquare(2,10)

Out[R]:

array([6.46906743, 1.74516249, 1.61624403, 1.95992536, 1.14905782,
       4.13322769, 0.41470648, 0.8892556 , 1.22484048, 3.3340893 ])

附录:常用数学分布介绍


6666666666666.png

6666666666666.png

6666666666666.png

6666666666666.png

如果喜欢,记得点赞哦!

目录
相关文章
|
2天前
|
存储 缓存 Java
Java 并发编程——volatile 关键字解析
本文介绍了Java线程中的`volatile`关键字及其与`synchronized`锁的区别。`volatile`保证了变量的可见性和一定的有序性,但不能保证原子性。它通过内存屏障实现,避免指令重排序,确保线程间数据一致。相比`synchronized`,`volatile`性能更优,适用于简单状态标记和某些特定场景,如单例模式中的双重检查锁定。文中还解释了Java内存模型的基本概念,包括主内存、工作内存及并发编程中的原子性、可见性和有序性。
Java 并发编程——volatile 关键字解析
|
8天前
|
数据采集 JSON API
如何利用Python爬虫淘宝商品详情高级版(item_get_pro)API接口及返回值解析说明
本文介绍了如何利用Python爬虫技术调用淘宝商品详情高级版API接口(item_get_pro),获取商品的详细信息,包括标题、价格、销量等。文章涵盖了环境准备、API权限申请、请求构建和返回值解析等内容,强调了数据获取的合规性和安全性。
|
12天前
|
数据可视化 算法 数据挖掘
Python量化投资实践:基于蒙特卡洛模拟的投资组合风险建模与分析
蒙特卡洛模拟是一种利用重复随机抽样解决确定性问题的计算方法,广泛应用于金融领域的不确定性建模和风险评估。本文介绍如何使用Python和EODHD API获取历史交易数据,通过模拟生成未来价格路径,分析投资风险与收益,包括VaR和CVaR计算,以辅助投资者制定合理决策。
58 15
|
6天前
|
数据挖掘 vr&ar C++
让UE自动运行Python脚本:实现与实例解析
本文介绍如何配置Unreal Engine(UE)以自动运行Python脚本,提高开发效率。通过安装Python、配置UE环境及使用第三方插件,实现Python与UE的集成。结合蓝图和C++示例,展示自动化任务处理、关卡生成及数据分析等应用场景。
47 5
|
9天前
|
缓存 数据安全/隐私保护 Python
python装饰器底层原理
Python装饰器是一个强大的工具,可以在不修改原始函数代码的情况下,动态地增加功能。理解装饰器的底层原理,包括函数是对象、闭包和高阶函数,可以帮助我们更好地使用和编写装饰器。无论是用于日志记录、权限验证还是缓存,装饰器都可以显著提高代码的可维护性和复用性。
21 5
|
20天前
|
测试技术 开发者 Python
探索Python中的装饰器:从入门到实践
装饰器,在Python中是一块强大的语法糖,它允许我们在不修改原函数代码的情况下增加额外的功能。本文将通过简单易懂的语言和实例,带你一步步了解装饰器的基本概念、使用方法以及如何自定义装饰器。我们还将探讨装饰器在实战中的应用,让你能够在实际编程中灵活运用这一技术。
37 7
|
19天前
|
存储 缓存 Python
Python中的装饰器深度解析与实践
在Python的世界里,装饰器如同一位神秘的魔法师,它拥有改变函数行为的能力。本文将揭开装饰器的神秘面纱,通过直观的代码示例,引导你理解其工作原理,并掌握如何在实际项目中灵活运用这一强大的工具。从基础到进阶,我们将一起探索装饰器的魅力所在。
|
23天前
|
存储 编译器 C语言
【C语言】数据类型全解析:编程效率提升的秘诀
在C语言中,合理选择和使用数据类型是编程的关键。通过深入理解基本数据类型和派生数据类型,掌握类型限定符和扩展技巧,可以编写出高效、稳定、可维护的代码。无论是在普通应用还是嵌入式系统中,数据类型的合理使用都能显著提升程序的性能和可靠性。
41 8
|
21天前
|
开发者 Python
Python中的装饰器:从入门到实践
本文将深入探讨Python的装饰器,这一强大工具允许开发者在不修改现有函数代码的情况下增加额外的功能。我们将通过实例学习如何创建和应用装饰器,并探索它们背后的原理和高级用法。
35 5
|
23天前
|
Android开发 开发者 Python
通过标签清理微信好友:Python自动化脚本解析
微信已成为日常生活中的重要社交工具,但随着使用时间增长,好友列表可能变得臃肿。本文介绍了一个基于 Python 的自动化脚本,利用 `uiautomator2` 库,通过模拟用户操作实现根据标签批量清理微信好友的功能。脚本包括环境准备、类定义、方法实现等部分,详细解析了如何通过标签筛选并删除好友,适合需要批量管理微信好友的用户。
32 7