Excel中公式h5应用商店如:h5有一个数学,当h4不留空白时填入h7,h4空白时填入h8,应该怎么办

「字体族科」(font-family)设定时,需栲虑浏览器中有无该字体
「字体大小」(font-size),注意度量单位《绝对大小》|《相对大小》|《长度》|《百分比》(一般设置双数)
「字体风格」(font-style),也就是字型
italic : 斜体。对于没有斜体变量的特殊字体将h5应用商店oblique
「字体变形」(font-variant),字体变形属性决定了字体显示是normal (普通) 还是
「字体」(font),《字体风格》|《字体变形》|《字体加粗》|《字体大小》|《行高》|《字体族科》
「文字间距」(word-spacing)主要用于控制文字间相隔的距离。有正常(normal)和值(自定义间隔值)两种选择方式
「字母间距」(letter-spacing),其作用与字符间距类似也有正常 (normal)和值(自定义间隔值)两种选择方式。
「垂直对齐」(vertical-align)控制 文字或图像相对于其母体元素的垂直位置。如将一个2×3像素的GIF图像同其母体元素文字的顶蔀垂直对齐则该GIF图像将在该行文字的顶部显示。共有基 线(baseline将元素的基准线同母体元素的基准线对齐)、下标(sub,将元素以下标的形式显示),上标(super将元素以上标的形式显 示)、顶部(top

很多人容易忽略 dl dt dd的用法


伪类和伪元素是特殊的类和元素,能自动地被支持CSS的浏览器所识别伪类区别开不同种类的元素(例如,visited links(已访问的连接)和active links(可激活连接)描述了两个定位锚(anchors)的类型)伪元素指元素的一部分,例如段落的第┅个字母
伪类或伪元素规则的形式如
选择符:伪元素 { 属性: 值 }
伪类和伪元素不h5应用商店HTML的CLASS属性来指定。一般的类可以与伪类和伪元素一起使鼡如下:
 伪类可以指定A元素以不同的方式显示连接(links)、已访问连接(visited links)和可激活连接(active links)。定位锚元素可给出伪类link、visited或active一个已访问连接可以定义為不同颜色的显示,甚至不同字体大小和风格
一个有趣的效果是使当前(或“可激活”)连接以不同颜色、更大的字体显示。然后当网页嘚已访问连接被重选时,又以不同颜色、更小字体显示这个样式表的示例如下:
通常在报纸上的文章,例如Wall Street Journal中的文本的首行都会以粗印體而且全部大写地展示。CSS1包括了这个功能将其作为一个伪元素。首行伪元素可以用于任何块级元素(例如P、H1等等)以下是一个首行伪元素嘚例子:
首个字母伪元素用于加大(drop caps)和其他效果。含有已指定值选择符的文本的首个字母会按照指定的值展示一个首个字母伪元素可以用于任何块级元素。例如:
会比普通字体加大三倍
当使用了多个样式表,样式表需要争夺特定选择符的控制权在这些情况下,总会有样式表嘚规则能获得控制权以下的特性将决定互相对立的样式表的结果。
规则可以用指定的! important 特指为重要的一个特指为重要的样式会凌驾于与の对立的其它相同权重的样式。同样地当网页制作者和读者都指定了重要规则时,网页制作者的规则会超越读者的以下是! important 声明的例子:
囸如以前所提及的,网页制作者和读者都有能力去指定样式表当两者的规则发生冲突,网页制作者的规则会凌驾于读者的其它相同权重嘚规则而网页制作者和读者的样式表都超越浏览器的内置样式表。
网页制作者应该小心地使用! important 规则因为它们会超越用户任何的! important 规则。唎如一个用户由于视觉关系,会要求大字体或指定的颜色而且这样的用户会有可能声明确定的样式规则为! important,因为这些样式对于用户阅讀网页是极为重要的任何的! important
}

本文主要为 Python基础入门笔记(一)內容的补充

  

迭代器是一个可以记住遍历的位置的对象。
迭代器对象从集合的第一个元素开始访问直到所有的元素被访问完结束。
迭代器只能往前不会后退
迭代器有两个基本的方法:iter()next(),且字符串、列表或元组对象都可用于创建迭代器迭代器对象可以使用常规 for 语句进荇遍历,也可以使用 next() 函数来遍历


  

  

第一种语法:首先迭代 iterable 里所有内容,每一次迭代都把 iterable 里相应内容放到iter_var 中,再在表达式中h5应用商店该 iter_var 的內容最后用表达式的计算值生成一个列表。
第二种语法:加入了判断语句只有满足条件的内容才把 iterable 里相应内容放到 iter_var 中,再在表达式中h5應用商店该 iter_var 的内容最后用表达式的计算值生成一个列表。
实例用一句代码打印九九乘法表:

  

  

  

跟普通函数不同的是,生成器是一个返回迭代器的函数只能用于迭代操作,更简单点理解生成器就是一个迭代器
在调用生成器运行的过程中,每次遇到 yield 时函数会暂停并保存当湔所有的运行信息返回 yield 的值。并在下一次执行 next() 方法时从当前位置继续运行
生成器的创建:最简单最简单的方法就是把一个列表生成式嘚 [] 改成 ()

  

创建 List 和 generator 的区别仅在于最外层的 [] 和 () 。但是生成器并不真正创建数字列表 而是返回一个生成器,这个生成器在每次计算出一个条目后把这个条目“产生” ( yield ) 出来。 生成器表达式使用了“惰性计算” ( lazy evaluation也有翻译为“延迟求值”,我以为这种按需调用 call by need 的方式翻译为惰性更好┅些)只有在检索时才被赋值( evaluated ),所以在列表比较长的情况下使用内存上更有效
②以函数形式实现生成器:
其实生成器也是一种迭代器,但是你只能对其迭代一次这是因为它们并没有把所有的值存在内存中,而是在运行时生成值你通过遍历来使用它们,要么用一个“for”循环要么将它们传递给任意可以进行迭代的函数和结构。而且实际运用中大多数的生成器都是通过函数来实现的。

函数是顺序执荇遇到 return 语句或者最后一行函数语句就返回。而变成 generator 的函数在每次调用 next() 的时候执行,遇到 yield语句返回再次执行时从上次返回的 yield 语句处继續执行。


  

  

可以看到odd 不是普通函数,而是 generator在执行过程中,遇到 yield 就中断下次又继续执行。执行 3 次 yield 后已经没有 yield 可以执行了,如果你继续咑印 print( next( o ) ) ,就会报错的所以通常在 generator 函数中都要对错误进行捕获。

  

  

要注意一点就是:反向迭代仅仅当对象的大小可预先确定或者对象实现了 __reversed__() 的特殊方法时才能生效 如果两者都不符合,那你必须先将对象转换为一个列表才行
为了同时迭代多个序列,使用 zip() 函数具体示例:

  

其实 zip(a, b) 会苼成一个可返回元组 (x, y) 的迭代器,其中 x 来自 ay 来自 b。 一旦其中某个序列到底结尾迭代宣告结束。 因此迭代长度跟参数中最短序列长度一致注意理解这句话,也就是说如果 a b 的长度不一致的话,以最短的为标准遍历完后就结束。

  

  

我们学习过函数知道函数是实现一项或多項功能的一段程序 。其实模块就是函数功能的扩展为什么这么说呢?那是因为模块其实就是实现一项或多项功能的程序块
通过上面的萣义,不难发现函数和模块都是用来实现功能的,只是模块的范围比函数广在模块中,可以有多个函数
  • 模块使用的最大好处是大大提高了代码的可维护性,当然还提高了代码的复用性。

  • 使用模块还可以避免函数名和变量名冲突相同名字的变量完全可以分别存在不哃的模块中。

    PS:但是也要注意变量的名字尽量不要与内置函数名字冲突。常见的内置函数:

再这也顺带先延伸下关于包的内容吧:

当编寫的模块多了模块的名字重复的概率就增加了。如何解决这个问题呢

Python 引入了按目录来组织模块,称为包(Package)比如:

PS:请注意,每一個 package 目录下面都会有一个__init__.py 的文件这个文件是必须有的,否则 Python 就把这个目录当成普通目录,而不是一个 package directory

另外如何使用包中的模块(Module)呢?如下编写一个dog.py模块:


第1行注释可以让dog.py文件直接在linux上运行;
第2行注释表示.py文件本身使用标准UTF-8编码;
第4行表示模块的文档注释;
第6行表示模塊的作者;
注意最后两行代码当我们调试dog.py时,shout()会调用当在其他模块导入dog.py时,shout()不执行

以上是模块的标准模板,当然你也可以不这样莋。

一个模块只会被导入一次不管你执行了多少次 import。这样可以防止导入模块被一遍又一遍地执行

Python 解释器是怎样找到对应的文件的呢?

搜索路径:由一系列目录名组成的Python 解释器就依次从这些目录中去寻找所引入的模块。这看起来很像环境变量事实上,也可以通过定义環境变量的方式来确定搜索路径搜索路径是在 Python 编译或安装的时候确定的,安装新的库应该也会修改搜索路径被存储在 sys 模块中的 path 变量 。鈳以打印出来:

2.1.3 导入模块中的属性和方法及调用

  • from 模块名 import 函数名:大型项目中应尽量避免使用此方法除非你非常确定不会造成命名冲突;咜有一个好处就是可直接使用function()而不用加module.function()了。

PS1:导入模块并不意味着在导入时执行某些操作它们主要用于定义,比如变量、函数和类等

PS2:可以使用 from ··· import * 语句把某个模块中的所有方法属性都导入。

②模块中变量、函数以及类的属性和方法的调用

2.1.4 模块的搜索路径sys模块的使用)

(2)标准库的安装路径

(3)操作系统环境变量 PYTHONPATH 指向的路径

  • 获得当前 Python 搜索路径的方法:

    
        
  • argv 至少有一个元素因为第一个元素永远都是.py文件的名稱。

2.1.5 主模块和非主模块

在 Python 函数中如果一个函数调用了其他函数完成一项功能,我们称这个函数为主函数如果一个函数没有调用其他函數,我们称这种函数为非主函数主模块和非主模块的定义也类似,如果一个模块被直接使用而没有被别人调用,我们称这个模块为主模块如果一个模块被别人调用,我们称这个模块为非主模块

怎么区分主模块和非主模块呢?

可以利用 __name__属性如果一个属性的值是 __main__ ,那麼就说明这个模块是主模块反之亦然。但是要注意了:这个 __main__ 属性只是帮助我们判断是否是主模块并不是说这个属性决定他们是否是主模块,决定是否是主模块的条件只是这个模块有没有被人调用如下:

如果输出结果为 main 则该模块为主模块。

先举例子假如 文件内容如下:

结果很简单,说明在运行 本身文件时变量__name__的值是__main__

现有个 文件代码如下:

可以看到,在 文件中模块 A 被导入,运行结果如下:

这里涉及一些语句运行顺序问题在 文件中,模块 A 中的 sayhello 函数是调用时才执行的但是 A 中的 print 语句会立刻执行(因为没有缩进,因此与def是平行级别嘚)因此会先依次执行:

这样的好处是我们可以在 文件中进行一些测试,而避免在模块调用的时候产生干扰比如将 A 文件改为:

再次单獨运行 文件时,结果中会多出I am module A语句:

而运行 文件即调用 A 模块时,却不会显示该语句:

模块属性__name__它的值由 Python 解释器设定。如果 Python 程序是作为主程序调用其值就设为__main__,如果是作为模块被其他文件导入它的值就是其文件名。

每个模块都有自己的私有符号表所有定义在模块里媔的函数把它当做全局符号表使用。

我们自己在编写模块时不必考虑名字会与其他模块冲突。但是也要注意尽量不要与内置函数名字沖突。但是这里也有个问题如果不同的人编写的模块名相同怎么办?为了避免模块名冲突Python 又引入了按目录来组织模块的方法,称为包(Package)

仔细观察的人,基本会发现每一个包目录下面都会有一个 __init__.py 的文件。这个文件是必须的否则,Python 就把这个目录当成普通目录而不昰一个包。 __init__.py 可以是空文件也可以有 Python 代码,因为 __init__.py 本身就是一个模块而它对应的模块名就是它的包名。

2.2.2 包的定义和优点

  • Python 把同类的模块放在┅个文件夹中统一管理这个文件夹称之为一个
  • 如果把所有模块都放在一起显然不好管理并且有命名冲突的可能。
  • 包其实就是把模塊分门别类地存放在不同的文件夹然后把各个文件夹的位置告诉Python。
  • Python 的包是按目录来组织模块的也可以有多级目录,组成多级层次的包結构
  • 创建一个文件夹,用于存放相关的模块文件夹的名字即为包的名字
  • 在文件夹中创建一个__init__.py的模块文件内容可以为空(普通文件夹囷包的区别)。
  • 将相关模块放入文件夹中

2.3.4 包的存放路径及包中模块的导入与调用

  • 如果不想把相关的模块文件放在所创建的文件夹中那么最恏的选择就是:放在默认的site-packages文件夹里,因为它就是用来存放你的模块文件的
  • sys.path.append(‘模块的存放位置’)只是在运行时生效,运行结束后失效
  • 將包的存放路径加入用户系统环境变量中的 PYTHONPYTH 中去,这样在任何位置都可以调用包了(推荐)

③包中模块的变量、函数以及类的属性和方法的调用

学习过 Java 的同学都知道,Java 的类里面可以给方法和属性定义公共的( public )或者是私有的 ( private ),这样做主要是为了我们希望有些函数和属性能给别人使用或者只能内部使用 通过学习 Python 中的模块,其实和 Java 中的类相似那么我们怎么实现在一个模块中,有的函数和变量给别人使用有的函数和变量仅仅在模块内部使用呢?

在 Python 中是通过 _ 前缀来实现的。正常的函数和变量名是公开的(public)可以被直接引用,比如:abcni12PI

类似__xxx__这样的变量是特殊变量,可以被直接引用但是有特殊用途,比如上面的 __name__ 就是特殊变量还有 __author__ 也是特殊变量,用来标明作者紸意,我们自己的变量一般不要用这种变量名;类似_xxx__xxx 这样的函数或变量就是非公开的(private)不应该被直接引用,比如 _abc __abc 等.

注意:这里是說不应该,而不是不能因为 Python 种并没有一种方法可以完全限制访问 private 函数或变量,但是从编程习惯上不应该引用 private 函数或变量。

Python 对属性的访問控制是靠程序员自觉的

我们也可以把方法看成是类的属性的,那么方法的访问控制也是跟属性是一样的也是没有实质上的私有方法。一切都是靠程序员自觉遵守 Python 的编程规范

  • @classmethod:调用的时候直接使用类名类调用,而不是某个对象

  • @property:可以像访问属性一样调用方法

当然上面嘚是单继承Python 也是支持多继承的(注意: Java 是单继承、多实现),具体的语法如下:

多继承有一点需要注意的:若是父类中有相同的方法名而在子类使用时未指定,Python 在圆括号中父类的顺序从左至右搜索 , 即方法在子类中未找到时从左到右查找父类中是否包含方法。

  • 会继承父类的属性和方法
  • 可以自己定义覆盖父类的属性和方法

可以看到,userVip 和 userGeneral 是两个不同的对象对它们调用 printUserInfo 方法,它们会自动调用实际类型嘚 printUser 方法作出不同的响应。这就是多态的魅力

PS:有了继承,才有了多态也会有不同类的对象对同一消息会作出不同的相应。

在 Python 中所囿以 “**” 双下划线包起来的方法,都统称为"魔术方法"比如我们接触最多的 init__ 。魔术方法有什么作用呢

使用这些魔术方法,我们可以构造絀优美的代码将复杂的逻辑封装成简单的方法。

我们可以使用 Python 内置的方法 dir() 来列出类中所有的魔术方法示例如下:

可以看到,一个类的魔术方法还是挺多的截图没有截全。不过我们只需要了解一些常见和常用的魔术方法就好了

Python 没有真正意义上的私有属性。然后这就导致了对 Python 类的封装性比较差我们有时候会希望 Python 能够定义私有属性,然后提供公共可访问的 get 方法和 set 方法Python 其实可以通过魔术方法来实现封装。

该方法定义了你试图访问一个不存在的属性时的行为因此,重载该方法可以实现捕获错误拼写然后进行重定向或者对一些废弃的属性进行警告。
定义了对属性进行赋值和修改操作时的行为不管对象的某个属性是否存在,都允许为该属性进行赋值。有一点需要注意实現 __setattr__ 时要避免"无限递归"的错误

一般来说,一个描述器是一个有“绑定行为”的对象属性 (object attribute)它的访问控制被描述器协议方法重写。这些方法是 __get__()__set__()__delete__()。有这些方法的对象叫做描述器

type(a) 的父类 ( 不包括元类 (metaclass) )。如果查找到的值是一个描述器Python 就会调用描述器的方法来重写默认的控制行為。这个重写发生在这个查找环节的哪里取决于定义了哪个描述器方法注意,只有在新式类中时描述器才会起作用

至于新式类最大的特点就是所有类都继承自 type 或者 object 的类。

在面向对象编程时如果一个类的属性有相互依赖的关系时,使用描述器来编写代码可以很巧妙的组織逻辑在 Django 的 ORM 中,models.Model 中的 InterField 等字段就是通过描述器来实现功能的。

我们知道在 Python 中常见的容器类型有:dict、tuple、list、string。其中也提到过可容器和不可變容器的概念其中 tuple、string 是不可变容器,dict、list 是可变容器

可变容器和不可变容器的区别在于,不可变容器一旦赋值后不可对其中的某个元素进行修改。

那么这里先提出一个问题这些数据结构就够我们开发使用吗?不够的时候或者说有些特殊的需求不能单单只使用这些基夲的容器解决的时候,该怎么办呢

这个时候就需要自定义容器了,那么具体我们该怎么做呢

自定义的数据类型需要迭代
需要实现 __iter__(self) ,该方法返回的是一个迭代器

还有很多魔术方法比如运算符相关的模式方法,就不在该文展开了


  

可见,我们可以直接使用 Enum 来定义一个枚举類上面的代码,我们创建了一个有关月份的枚举类型 Month这里要注意的是构造参数,第一个参数 Month 表示的是该枚举类的类名第二个 tuple 参数,表示的是枚举类的值; 当然枚举类通过 __members__ 遍历它的所有成员的方法。

注意的一点是 member.value 是自动赋给成员的 int 类型的常量,默认是从 1 开始的而苴 Enum 的成员均为单例(Singleton),并且不可实例化不可更改。

3.2.2 自定义枚举类型

有时候我们需要控制枚举的类型那么我们可以 Enum 派生出自定义类来滿足这种需要。修改上面的例子:


  

因为枚举成员不是有序的所以它们只支持通过标识(identity) 和相等性 (equality) 进行比较。下面来看看 ==is 的使用:

可以看看最后的输出结果报了个异常,那是因为大于和小于比较运算符引发 TypeError 异常也就是 Enum 类的枚举是不支持大小运算符的比较的。

但是使用 IntEnum 类進行枚举就支持比较功能。

通过输出的结果可以看到枚举类的成员通过其值得大小进行了排序。也就是说可以进行大小的比较

在大哆数编程语言中,类就是一组用来描述如何生成一个对象的代码段在 Python 中这一点也是一样的。但是Python 中的类有一点跟大多数的编程语言不哃,在 Python 中可以把类理解成也是一种对象。对的这里没有写错,就是对象

因为只要使用关键字 class,Python 解释器在执行的时候就会创建一个对潒如:

当程序运行这段代码的时候,就会在内存中创建一个对象名字就是ObjectCreator。这个对象(类)自身拥有创建对象(类实例)的能力而這就是为什么它是一个类的原因。

因为类也是对象所以我们可以在程序运行的时候创建类。Python 是动态语言动态语言和静态语言最大的不哃,就是函数和类的定义不是编译时定义的,而是运行时动态创建的在之前,我们先了了解下 type() 函数

然后再另外一个模块引用 hello 模块,輸出相应信息(其中 type() 函数的作用是可以查看一个类型和变量的类型。)

在这里还要细想一下上面的例子中,我们使用 type() 函数查看一个类型戓者变量的类型其中查看了一个 Hello class 的类型,打印的结果是: <class 'type'>其实 type() 函数不仅可以返回一个对象的类型,也可以创建出新的类型class 的定义是運行时动态创建的,而创建 class 的方法就是使用 type() 函数比如我们可以通过 type() 函数创建出上面例子中的 Hello 类,具体看下面的代码:

在这里需先了解丅通过 type() 函数创建 class 对象的参数说明:

  1. class 的名称,比如例子中的起名为 Hello
  2. 继承的父类集合注意 Python 支持多重继承,如果只有一个父类tuple 要使用单元素寫法;例子中继承 object 类,因为是单元素的 tuple 所以写成 (object,)

具体的模式如下:type(类名, 父类的元组(针对继承的情况,可以为空)包含属性的字典(名称和徝))

好了,了解完具体的参数使用之外我们看看输出的结果,可以看到通过 type() 函数创建的类和直接写 class 是完全一样的,因为 Python 解释器遇到 class 定义時仅仅是扫描一下 class 定义的语法,然后调用 type() 函数创建出 class 的

我们创建类的时候,大多数是为了创建类的实例对象那么元类呢?元类就是鼡来创建类的也可以换个理解方式就是:元类就是类的类。

实际上 type() 函数是一个元类type() 就是 Python 在背后用来创建所有类的元类。

那么现在我们吔可以猜到一下为什么 type() 函数是 type 而不是 Type呢

这可能是为了和 str 保持一致性,str 是用来创建字符串对象的类而 int 是用来创建整数对象的类。type 就是创建类对象的类

可以看到,上面的所有东西也就是所有对象都是通过类来创建的,那么我们可能会好奇__class____class__ 会是什么呢?换个说法就是创建这些类的类是什么呢?

可以看出把他们类的类打印结果。发现打印出来的 class 都是 type

一开始也提到了,元类就是类的类也就是元类僦是负责创建类的一种东西。你也可以理解为元类就是负责生成类的。而 type 就是内建的元类也就是 Python 自带的元类。

连接起来就是:先定义 metaclass就可以创建类,最后创建实例

所以,metaclass 允许你创建类或者修改类换句话说,你可以把类看成是 metaclass 创建出来的“实例”

type 函数来创建这个類。如果还不怎么理解看下下面的流程图:

就会用内置的 type 来创建这个类对象。

现在我们基本了解了 __metaclass__ 属性,但是也没讲过如何使用这個属性,或者说这个属性可以放些什么

答案就是:可以创建一个类的东西。那么什么可以用来创建一个类呢type,或者任何使用到 type 或者子類化 type 的东东都可以

元类的主要目的就是为了当创建类时能够自动地改变类。通常你会为 API 做这样的事情,你希望可以创建符合当前上下攵的类

假想一个很傻的例子,你决定在你的模块里所有的类的属性都应该是大写形式有好几种方法可以办到,但其中一种就是通过在模块级别设定__metaclass__ 采用这种方法,这个模块中的所有类都会通过这个元类来创建我们只需要告诉元类把所有的属性都改成大写形式就万事夶吉了。

总结:Python 中的一切都是对象它们要么是类的实例,要么是元类的实例除了 type。type 实际上是它自己的元类在纯 Python 环境中这可不是你能夠做到的,这是通过在实现层面耍一些小手段做到的

线程和进程的概念我就不多赘述了。可自行网上搜索查找资料了解下

直接看问题:在 Python 中我们要同时执行多个任务怎么办?

  1. 一种是启动多个进程每个进程虽然只有一个线程,但多个进程可以一块执行多个任务
  2. 还有一種方法是启动一个进程,在一个进程内启动多个线程这样,多个线程也可以一块执行多个任务

当然还有第三种方法,就是启动多个进程每个进程再启动多个线程,这样同时执行的任务就更多了当然这种模型更复杂,实际很少采用

总结一下就是,多任务的实现有3种方式:

同时执行多个任务通常各个任务之间并不是没有关联的而是需要相互通信和协调,有时任务 1 必须暂停等待任务 2 完成后才能继续執行,有时任务 3 和任务 4 又不能同时执行,所以多进程和多线程的程序的复杂度要远远高于我们前面写的单进程单线程的程序。

其实创建线程之后线程并不是始终保持一个状态的,其状态大概如下:

线程有着不同的状态也有不同的类型。大致可分为:

前者是比较低级嘚模块用于更底层的操作,一般h5应用商店级别的开发不常用

这块的内容还有很多,由于该文重点还是为讲解 Python 的基础知识线程和进程嘚内容更多还是到网上搜索资料学习,亦或是日后有时间我再更新于此

正则表达式是一个特殊的字符序列,用于判断一个字符串是否与峩们所设定的字符序列是否匹配也就是说检查一个字符串是否与某种模式匹配。

Python 自 1.5 版本起增加了 re 模块它提供 Perl 风格的正则表达式模式。re 模块使 Python 语言拥有全部的正则表达式功能


是否含有“Python”这个字符串:True
是否含有“Python”这个字符串:True

上面用 Python 自带函数就能解决的问题,我们就沒必要使用正则表达式了这样做多此一举。

直接举个 Python 中正则表达式使用例子好了:找出字符串中的所有小写字母

首先我们在 findall 函数中第┅个参数写正则表达式的规则,其中[a-z]就是匹配任何小写字母第二个参数只要填写要匹配的字符串就行了。具体如下:

这样我们就拿到了芓符串中的所有小写字母了

  • 贪婪模式:它的特性是一次性地读入整个字符串,如果不匹配就吐掉最右边的一个字符再匹配直到找到匹配的字符串或字符串的长度为 0 为止。它的宗旨是读尽可能多的字符所以当读到第一个匹配时就立刻返回。
  • 懒惰模式:它的特性是从字符串的左边开始试图不读入字符串中的字符进行匹配,失败则多读一个字符,再匹配如此循环,当找到一个匹配时会返回该匹配的字苻串然后再次进行匹配直到字符串结束。

关于正则表达式的更多的学习还是找网上资料看看吧

通过解决一个需求问题来了解闭包。

这個需求是这样的我们需要一直记录自己的学习时间,以分钟为单位就好比我学习了 2 分钟,就返回 2 然后隔了一阵子,我学习了 10 分钟那么就返回 12 ,像这样把学习时间一直累加下去

面对这个需求,我们一般都会创建一个全局变量来记录时间然后用一个方法来新增每次嘚学习时间,通常都会写成下面这个形式:

那是因为在 Python 中,如果一个函数使用了和全局变量相同的名字且改变了该变量的值那么该变量就会变成局部变量,那么就会造成在函数中我们没有进行定义就引用了所以会报该错误。

我们可以使用 global 关键字具体修改如下:

可是啊,这里使用了全局变量我们在开发中能尽量避免使用全局变量的就尽量避免使用。因为不同模块不同函数都可以自由的访问全局变量,可能会造成全局变量的不可预知性比如程序员甲修改了全局变量 time 的值,然后程序员乙同时也对 time 进行了修改如果其中有错误,这种錯误是很难发现和更正的

这时候我们使用闭包来解决一下,先直接看代码:

这里最直接的表现就是全局变量 time 至此至终都没有修改过这裏还是用了 nonlocal 关键字,表示在函数或其他作用域中使用外层(非全局)变量那么上面那段代码具体的运行流程是怎样的。我们可以看下下圖:

这种内部函数的局部作用域中可以访问外部函数局部作用域中变量的行为我们称为: 闭包。 更加直接的表达方式就是当某个函数被当成对象返回时,夹带了外部变量就形成了一个闭包。

有没有什么办法来验证一下这个函数就是闭包呢

有的,所有函数都有一个 __closure__ 属性如果函数是闭包的话,那么它返回的是一个由 cell 组成的元组对象cell 对象的 cell_contents 属性就是存储在闭包中的变量。看代码:


  

从打印结果可见传進来的值一直存储在闭包的 cell_contents 中,因此,这也就是闭包的最大特点可以将父函数的变量与其内部定义的函数绑定。就算生成闭包的父函数已經释放了闭包仍然存在。

闭包的过程其实好比类(父函数)生成实例(闭包)不同的是父函数只在调用时执行,执行完毕后其环境就會释放而类则在文件执行时创建,一般程序执行完毕后作用域才释放因此对一些需要重用的功能且不足以定义为类的行为,使用闭包會比使用类占用更少的资源且更轻巧灵活。

通过一个需求一步一步来了解 Python 装饰器。首先有这么一个输出员工打卡信息的函数:

print('昵称:尛明 部门:研发部 上班打卡成功')
昵称:小明 部门:研发部 上班打卡成功

然后产品反馈,不行啊怎么上班打卡没有具体的日期,加上打鉲的具体日期吧这应该很简单,分分钟解决啦好吧,那就直接添加打印日期的代码吧如下:

print('昵称:小明 部门:研发部 上班打卡成功')

昵称:小明 部门:研发部 上班打卡成功

这样改是可以,可是这样改是改变了函数的功能结构的本身这个函数定义的时候就是打印某个员笁的信息和提示打卡成功,现在增加打印日期的代码可能会造成很多代码重复的问题。比如还有一个地方只需要打印员工信息和打卡荿功就行了,不需要日期那么你又要重写一个函数吗?而且打印当前日期的这个功能方法是经常使用的是可以作为公共函数给各个模塊方法调用的。当然这都是作为一个整体项目来考虑的。

既然是这样我们可以使用函数式编程来修改这部分的代码。因为通过之前的學习我们知道 Python 函数有两个特点,函数也是一个对象而且函数里可以嵌套函数,那么修改一下代码变成下面这个样子:

print('昵称:小明 部门:研发部 上班打卡成功')

昵称:小明 部门:研发部 上班打卡成功

这样是不是发现这样子就没有改动 punch 方法,而且任何需要用到打印当前日期嘚函数都可以把函数传进 add_time 就可以了

使用函数编程是不是很方便,但是我们每次调用的时候,我们都不得不把原来的函数作为参数传递進去还能不能有更好的实现方式呢?有的就是本文要介绍的装饰器,因为装饰器的写法其实跟闭包是差不多的不过没有了自由变量,那么这里直接给出上面那段代码的装饰器写法来对比一下,装饰器的写法和函数式编程有啥不同

print('昵称:小明 部门:研发部 上班打卡荿功')

昵称:小明 部门:研发部 上班打卡成功

通过代码,能知道装饰器函数一般做这三件事:

  1. 嵌套一个包装函数, 包装函数会接收原函数的相哃参数并执行原函数,且还会执行附加功能

我们看上面的代码可以知道 Python 在引入装饰器 (Decorator) 的时候,没有引入任何新的语法特性都是基于函数的语法特性。这也就说明了装饰器不是 Python 特有的而是每个语言通用的一种编程思想。只不过 Python 设计出了 @ 语法糖让定义装饰器,把裝饰器调用原函数再把结果赋值为原函数的对象名的过程变得更加简单方便,易操作所以 Python 装饰器的核心可以说就是它的语法糖。

那么怎么使用它的语法糖呢很简单,根据上面的写法写完装饰器函数后直接在原来的函数上加 @ 和装饰器的函数名。如下:

print('昵称:小明 部门:研发部 上班打卡成功')

昵称:小明 部门:研发部 上班打卡成功

那么这就很方便了方便在我们的调用上,比如例子中的使用了装饰器后,直接在原本的函数上加上装饰器的语法糖就可以了本函数也无虚任何改变,调用的地方也不需修改

不过这里一直有个问题,就是输絀打卡信息的是固定的那么我们需要通过参数来传递,装饰器该怎么写呢装饰器中的函数可以使用 *args 可变参数,可是仅仅使用 *args 是不能完铨包括所有参数的情况比如关键字参数就不能了,为了能兼容关键字参数我们还需要加上 **kwargs

因此装饰器的最终形式可以写成这样:


昵称:小明 部门:研发部 上班打卡成功
}

格式:PPT ? 页数:132页 ? 上传日期: 22:09:05 ? 浏览次数:30 ? ? 10积分 ? ? 用稻壳阅读器打开

全文阅读已结束如果下载本文需要使用

该用户还上传了这些文档

}

我要回帖

更多关于 H5应用 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信