Python-笔记1

原文链接:http://chenhao.space/post/29dd046f.html

笔记目标

Python基础
  • 函数
  • 面向对象
  • 文件操作和异常处理
  • 模块的使用
  • 装饰器、迭代器、生成器

函数

函数概述

例如:现在有这样一段代码

print(“天王盖地虎”)

print(“小鸡炖蘑菇”)

再来一段代码:在不同的地方相同的代码,那么这样的程序改如何设计

if 条件1:

print("天王盖地虎")

print("小鸡炖蘑菇")

elif 条件2:

print("天王盖地虎")

print("小鸡炖蘑菇")

elif 条件3:

print("天王盖地虎")

print("小鸡炖蘑菇")

如果需要输出多次,是否意味着要编写这块代码多次呢?

小总结:

如果在开发程序时,需要某块代码多次,但是为了提高编写的效率以及代码的重用,所以把具有独立功能的代码块组织为一个小模块,这就是函数
函数定义

函数定义的格式:

def 函数名():

    代码      
#案例:
    # 定义一个函数,能够完成打印信息的功能
def printInfo():
    print('------------------------------------')
    print('         人生苦短,我用Python')
    print('------------------------------------')

函数调用

定义了函数之后,就相当于有了一个具有某些功能的代码,想要让这些代码能够执行,需要调用它

调用函数很简单的,通过 函数名() 即可完成调用

# 定义完函数后,函数是不会自动执行的,需要调用它才可以
printInfo()
------------------------------------
         人生苦短,我用Python
------------------------------------
函数参数

概述:
思考一个问题,如下:

现在需要定义一个函数,这个函数能够完成2个数的加法运算,并且把结果打印出来,该怎样设计?下面的代码可以吗?有什么缺陷吗?
def message():
    name = input('请输入你的名字')
    age = input('请输入你的年龄')
    print(name,age)
    
message()    
请输入你的名字小吴
请输入你的年龄23
小吴 23
定义带有参数函数
def add2num():
    a = 11
    b = 22
    print(a+b)
add2num()    
33
def add2num(a,b):
    print(a+b)
add2num(10,20) 
30
调用带有参数的函数
总结
  • 定义时小括号中的参数,用来接收参数用的,称为 “形参”
  • 调用时小括号中的参数,用来传递给函数用的,称为 “实参”
函数的返回值

返回值:就是程序中函数完成一件事情后,最后给调用者的结果

注意:在python中return默认值为空–》None

def add2num(a,b):
    return a+b
sum = add2num(10,20) 
print(sum)
30
函数的参数

函数根据有没有参数,有没有返回值,可以相互组合,一共有4种

无参数,无返回值(此类函数,不能接收参数,也没有返回值,一般情况下,打印提示灯类似的功能,使用这类的函数)

无参数,有返回值(此类函数,不能接收参数,但是可以返回某个数据,一般情况下,像采集数据,用此类函数)

有参数,无返回值(此类函数,能接收参数,但不可以返回数据,一般情况下,对某些变量设置数据而不需结果时,用此类函数)

有参数,有返回值(此类函数,不仅能接收参数,还可以返回某个数据,一般情况下,像数据处理并需要结果的应用,用此类函数)

总结:
函数根据有没有参数,有没有返回值可以相互组合

定义函数时,是根据实际的功能需求来设计的,所以不同开发人员编写的函数类型各不相同

函数嵌套调用

一个函数里面又调用了另外一个函数,这就是所谓的函数嵌套调用

def testB():
    print('---- testB start----')
    print('这里是testB函数执行的代码...(省略)...')
    print('---- testB end----')

def testA():
    print('---- testA start----')
    testB()
    print('---- testA end----')

testA()
---- testA start----
---- testB start----
这里是testB函数执行的代码...(省略)...
---- testB end----
---- testA end----
关键字参数

定义:
允许函数调用时参数的顺序与定义时不一致

def myPrint(str,age):
    print(str,age)

myPrint('laowang',35)
myPrint(age=18,str='laosong')
laowang 35
laosong 18
默认参数(缺省参数)

概述:
python为了简化函数的调用,提供了默认参数机制
调用函数时,缺省参数的值如果没有传入,则被认为是默认值

def myPrint(str,sex,age = 35):
    print(str,sex,age)
    
myPrint('laowang','male')    
laowang male 35
不定长参数

概述:

有时可能需要一个函数能处理比当初声明时更多的参数。这些参数叫做不定长参数,声明时不会命名。

基本语法如下:

def functionname([formal_args,] *args, **kwargs):

"函数_文档字符串"
function_suite 
return [expression]

加了星号(*)的变量args会存放所有未命名的变量参数,args为元组;

而加**的变量kwargs会存放命名参数,即形如key=value的参数,

kwargs为字典。

def fun(a,b,*args,**kwargs):
    print('a =',a)
    print('b =',b)
    print('*args =',args)
    print('**kwargs =',kwargs)

#方式1
fun(1,2,3,4,5,m=6,n=7,p=8)
    
    
#方式2:
c = (3,4,5)
d = {'m': 6, 'n': 7, 'p': 8}
fun(1,2,*c,**d)
a = 1
b = 2
*args = (3, 4, 5)
**kwargs = {'p': 8, 'n': 7, 'm': 6}
a = 1
b = 2
*args = (3, 4, 5)
**kwargs = {'p': 8, 'n': 7, 'm': 6}

匿名函数

定义:
不使用def这样的语句定义函数,使用lambda来创建匿名函数

用lambda关键词能创建小型匿名函数。这种函数得名于省略了用def声明函数的标准步骤。

lambda函数的语法只包含一个语句,如下:

lambda [arg1 [,arg2,…argn]]:expression

或者:

lambda 参数1,参数2,……,参数n:expression

sum = lambda arg1,arg2:arg1+arg2

print(sum(10,20))
30
def fun(a,b,opt):
    print(a)
    print(b)
    print(opt(a,b))

fun(1,2,lambda x,y:x+y)

1
2
3
"""
特点:
1、lambda只是一个表达式,函数体比def简单
2、lambda的主体是一个表达式,而不是代码块,仅仅只能在lambda表达式中封装简单的逻辑
3、lambda函数有自己的命名空间,且不能访问自由参数列表之外的或全局命名空间的参数
4、虽然lambda是一个表达式且看起来只能写一行,与C和C++内联函数不同。


注意:
Lambda函数能接收任何数量的参数但只能返回一个表达式的值
匿名函数不能直接调用print,因为lambda需要一个表达式
"""
'\n特点:\n1、lambda只是一个表达式,函数体比def简单\n2、lambda的主体是一个表达式,而不是代码块,仅仅只能在lambda表达式中封装简单的逻辑\n3、lambda函数有自己的命名空间,且不能访问自由参数列表之外的或全局命名空间的参数\n4、虽然lambda是一个表达式且看起来只能写一行,与C和C++内联函数不同。\n\n\n注意:\nLambda函数能接收任何数量的参数但只能返回一个表达式的值\n匿名函数不能直接调用print,因为lambda需要一个表达式\n'
回调函数

定义:

回调函数就是一个通过函数指针调用的函数。如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,

我们就说这是回调函数。回调函数不是由该函数的实现方直接调用,而是在特定的事件或条件发生时由另外的一方调用的,用于对该事件或条件进行

响应

def double(x):
    return x*2

def quadruple(x):
    return x*4

#中间函数
def getOddNumber(k,getEvenNUmber):
    return 1 + getEvenNUmber(k)

def main():
    k = 1
    i = getOddNumber(k,double)
    print(i)
    i = getOddNumber(k,quadruple)
    print(i)
   
main()

3
5

面向对象

面向对象思想

面向过程:根据业务逻辑从上到下写代码

面向对象:将数据与函数绑定到一起,进行封装,这样能够更快速的开发程序,减少了重复代码的重写过程

面向过程编程最易被初学者接受,其往往用一长段代码来实现指定功能,开发过程的思路是将数据与函数按照执行的逻

辑顺序组织在一起,数据与函数分开考虑。

定义:

面向对象(object-oriented ;简称: OO) 至今还没有统一的概念 我这里把它定义为: 按人们 认识客观世界的系

统思维方式,采用基于对象(实体) 的概念建立模型,模拟客观世界分析、设 计、实现软件的办法。

面向对象编程(Object Oriented Programming-OOP) 是一种解决软件复用的设计和编程方法。 这种方法把软件

系统中相近相似的操作逻辑和操作 应用数据、状态,以类的型式描述出来,以对象实例的形式在软件系统中复用,以达

到提高软件开发效率的作用。

类和对象

面向对象编程的2个非常重要的概念:类和对象

对象是面向对象编程的核心,在使用对象的过程中,为了将具有共同特征和行为的一组对象抽象定义,

提出了另外一个新的概念——类

类就相当于制造飞机时的图纸,用它来进行创建的飞机就相当于对象

具有相似内部状态和运动规律的实体的集合(或统称为抽象)。

具有相同属性和行为事物的统称

定义:

类是抽象的,在使用的时候通常会找到这个类的一个具体的存在,使用这个具体的存在。一个类可以找到多个对象

对象

概述:

某一个具体事物的存在 ,在现实世界中可以是看得见摸得着的。

可以是直接使用的

总结:

类和对象之间的关系:

就像利用玩具的模型来创建多种不同的玩具

类就是创建对象的模板

区分类和对象

奔驰汽车 类

奔驰smart 类

张三的那辆奔驰smart 对象

狗 类

大黄狗 类

李四家那只大黄狗 对象

类的设计

类(Class) 由3个部分构成

类的名称:类名
类的属性:一组数据
类的方法:允许对进行操作的方法 (行为)

<1> 举例:

1)人类设计,只关心3样东西:

事物名称(类名):人(Person)
属性:身高(height)、年龄(age)
方法(行为/功能):跑(run)、打架(fight)

2)狗类的设计

类名:狗(Dog)
属性:品种 、毛色、性别、名字、 腿儿的数量
方法(行为/功能):叫 、跑、咬人、吃、摇尾巴
定义类
# 定义类
class Car:
    # 方法
    def getCarInfo(self):
        print('车轮子个数:%d, 颜色%s'%(self.wheelNum, self.color))

    def move(self):
        print("车正在移动...")
"""
说明:

    定义类时有2种:新式类和经典类,上面的Car为经典类,如果是Car(object)则为新式类
    类名 的命名规则按照"大驼峰"
 """   
'\n说明:\n\n    定义类时有2种:新式类和经典类,上面的Car为经典类,如果是Car(object)则为新式类\n    类名 的命名规则按照"大驼峰"\n '
对象创建

python中,可以根据已经定义的类去创建出一个个对象

创建对象的格式为:

对象名 = 类名()

BMW = Car()
BMW.move()
车正在移动...
init()

想一想:

在上一小节的demo中,我们已经给BMW这个对象添加了2个属性,wheelNum(车的轮胎数量)以及color(车的颜色),试想如果再次创建一个对象的话,肯定也需要进行添加属性,显然这样做很费事,那么有没有办法能够在创建对象的时候,就顺便把车这个对象的属性给设置呢?

答:
init()方法

使用方式:

def 类名:

#初始化函数,用来完成一些默认的设定

def __init__():

    pass
class Car:
    def __init__(self):
        self.wheelnum = 4
        self.color = '蓝色'

BMW = Car()
print(BMW.color)
蓝色
封装:
  • 数据封装

封装数据的主要原因是:保护隐私-私有属性

  • 方法封装

封装方法的主要原因是:隔离复杂度–函数封装


继承

继承的概念

在现实生活中,继承一般指的是子女继承父辈的财产

在程序中,继承描述的是事物之间的所属关系,例如猫和狗都属于动物,程序中便可以描述为猫和狗继承自动物;

同理,波斯猫和巴厘猫都继承自猫,而沙皮狗和斑点狗都继承足够,如下如所示:

格式:

子类在继承的时候,在定义类时,小括号()中为父类的名字

父类的属性、方法,会被继承给子类

单继承
#单继承
# 定义一个父类,如下:
class Cat(object):
    def __init__(self, name, color="白色"):
        self.name = name
        self.color = color
    def run(self):
        print("%s--在跑"%self.name)
        
# 定义一个子类,继承Cat类如下:
class Bosi(Cat):
    def setNewName(self, newName):
        self.name = newName

    def eat(self):
        print("%s--在吃"%self.name)


bs = Bosi("印度猫")
print('bs的名字为:%s'%bs.name)
print('bs的颜色为:%s'%bs.color)
bs.eat()
bs.setNewName('波斯')
bs.run()
bs的名字为:印度猫
bs的颜色为:白色
印度猫--在吃
波斯--在跑
#注意点:设置私有属性
class Animal(object):
    age = 13

    def __init__(self, name='动物', color='白色'):
        self.__name = name
        self.color = color

    def __test(self):
        print(self.__name)
        print(self.color)

    def test(self):
        print(self.__name)
        print(self.color)

class Dog(Animal):
    def dogTest1(self):
        #print(self.__name) #不能访问到父类的私有属性
        print(self.color)

    def dogTest2(self):
        #self.__test() #不能访问父类中的私有方法
        self.test()

A = Animal()
#print(A.__name) #程序出现异常,不能访问私有属性
print(A.color)
#A.__test() #程序出现异常,不能访问私有方法
A.test()

print("------分割线-----")

D = Dog(name = "小花狗", color = "黄色")
D.dogTest1()
D.dogTest2()
"""
总结:私有的属性,,不能通过对象直接访问,但是可以通过方法访问
    私有的方法  不能通过对象直接访问
    私有的属性、方法,不会被子类继承,也不能被访问  
    一般情况下,私有的属性、方法都是不对外公布的,往往用来做内部的事情,起到安全的作用
"""    
白色
动物
白色
------分割线-----
黄色
小花狗
黄色
'\n总结:私有的属性,,不能通过对象直接访问,但是可以通过方法访问\n    私有的方法  不能通过对象直接访问\n    私有的属性、方法,不会被子类继承,也不能被访问  \n    一般情况下,私有的属性、方法都是不对外公布的,往往用来做内部的事情,起到安全的作用\n'
多继承
"""
理解:
  骡子是马和驴的杂交品种
所谓多继承,即子类有多个父类,并且具有它们的特征  
"""
#Python中多继承的格式如下:
# 定义一个父类
class A:
    def printA(self):
        print('----A----')

# 定义一个父类
class B:
    def printB(self):
        print('----B----')

# 定义一个子类,继承自A、B
class C(A,B):
    @classmethod
    @staticmethod
    def printC(self):
        print('----C----')

obj_C = C()
obj_C.printA()
obj_C.printB()
----A----
----B----
多态

多态的概念是应用于Java和C#这一类强类型语言中,而Python崇尚“鸭子类型”。

所谓多态:定义时的类型和运行时的类型不一样,此时就成为多态

Python伪代码实现Java或C#的多态

一个父类有多个子类

类属性和实例属性

类属性就是类对象所拥有的属性,它被所有类对象的实例对象所共有,

在内存中只存在一个副本,这个和C++中类的静态成员变量有点类似。对于公有的类属性,

在类外可以通过类对象和实例对象访问

class People(object):
    name = 'Tom'
    __age = 12
    
p = People()
print(p.name)
print(People.name)
# print(p.__age)
# print(People.__age)

Tom
Tom
class People(object):
    address = 'beijing'
    def __init__(self):
        self.name = 'Tom'
        self.age = 12
        
p = People()
print(p.address)
print(p.name)
print(p.age)

print(People.address)
print(People.name)
# print(p.age)
beijing
Tom
12
beijing
---------------------------------------------------------------------------

AttributeError                            Traceback (most recent call last)

<ipython-input-22-e63e70d527d3> in <module>
     11 
     12 print(People.address)
---> 13 print(People.name)
     14 # print(p.age)
AttributeError: type object 'People' has no attribute 'name'

模块

目前代码比较少,写在一个文件中还体现不出什么缺点,但是随着代码量越来越多,代码就越来越难以维护。

为了解决难以维护的问题,我们把很多相似功能的函数分组,分别放到不同的文件中去。

这样每个文件所包含的内容相对较少,而且对于每一个文件的大致功能可用用文件名来体现。

很多编程语言都是这么来组织代码结构。一个.py文件就是一个模块

在Python中有一个概念叫做模块(module),这个和C语言中的头文件以及Java中的包很类似,

比如在Python中要调用sin函数,必须用import关键字引入math这个模块,下面就来了解一下Python中的模块。

说的通俗点:模块就好比是工具包,要想使用这个工具包中的工具(就好比函数),就需要导入这个模块

优点:

  • 提高代码的可维护性
  • 提高了代码的复用度,当一个模块完毕,可以被多个地方引用
  • 引用其他的模块(内置模块和三方模块和自定义模块)
  • 避免函数名和变量名的冲突
#常见的几种格式
import numpy
from numpy import abs
from numpy import *
from random import randrange as rr

文件操作

概述:

常见的txt/avi/html/zip/word等都称之为文件

文件作用:

存储数据

文件打开

在python,使用open函数,可以打开一个已经存在的文件,或者创建一个新文件

open(文件名,访问模式)

示例如下:

f = open('test.txt', 'w')

说明:
访问模式 说明
r 以只读方式打开文件。文件的指针将会放在文件的开头。这是默认模式。

w 打开一个文件只用于写入。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。

a 打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到

已有内容之后。如果该文件不存在,创建新文件进行写入。

rb 以二进制格式打开一个文件用于只读。文件指针将会放在文件的开头。这是默认模式。

wb 以二进制格式打开一个文件只用于写入。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。

ab 以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,

新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。

r+ 打开一个文件用于读写。文件指针将会放在文件的开头。

w+ 打开一个文件用于读写。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。

a+ 打开一个文件用于读写。如果该文件已存在,文件指针将会放在文件的结尾。文件打开时会是追加模式。

如果该文件不存在,创建新文件用于读写。

rb+ 以二进制格式打开一个文件用于读写。文件指针将会放在文件的开头。

wb+ 以二进制格式打开一个文件用于读写。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。

ab+ 以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。

如果该文件不存在,创建新文件用于读写。

文件关闭

使用函数:
close( )

#示例如下:
# 新建一个文件,文件名为:test.txt
f = open('test.txt', 'w')
    # 关闭这个文件
f.close()

文件读写

#写
#使用write()可以完成向文件写入数据
f = open('test.txt', 'w')
f.write('hello world, i am here!')
f.close()
"""
注意:
    如果文件不存在那么创建,如果存在那么就先清空,然后写入数据
"""    
#读取内容
#1.read()
#2.readlines()
#3.readline()
f = open('test.txt', 'r')
content = f.read(5)
print(content)
f.close()
文件定位读写

什么是定位?

通俗的讲就是找到一个合适的位置

在软件开发中文件的读写定为该如何实现?

获取当前读写的位置

在读写文件的过程中,如果想知道当前的位置,

可以使用tell()来获取,这里是光标开始的位置

定位到某个位置

如果在读写文件的过程中,需要从另外一个位置进行操作的话,可以使用seek()

文件重命名

os模块中的rename()可以完成对文件的重命名操作

格式:

rename(需要修改的文件名, 新的文件名)

import os
os.rename('test.txt','haht.txt')
文件删除

概述:os模块中的remove()可以完成对文件的删除操作

格式:

remove(待删除的文件名)

文件夹操作

创建文件夹

使用os模块中的mkdir()函数

格式:

mkdir(str)

获取当前目录

使用os模块中的getcwd()函数

格式:
getcwd()

获取目录列表

使用os模块中的listdir()函数

格式:
listdir()

删除文件夹

使用os模块中的rmdir()函数

rmdir(str)—>str:表示需要删除的文件夹名称

异常

异常的处理

当出现异常情况时改如何处理?

捕获异常

捕获异常的基本格式:

try…except…

else

咱们应该对else并不陌生,在if中,它的作用是当条件不满足时执行的实行;

同样在try…except…中也是如此,即如果没有捕获到异常,那么就执行else中的事情

try…finally…

try…finally…语句用来表达这样的情况:

在程序中,如果一个段代码必须要执行,即无论异常是否产生都要执行,那么此时就需要使用finally。

比如文件关闭,释放锁,把数据库连接返还给连接池等

自定义异常

你可以用raise语句来引发一个异常

class ShortInputException(Exception):
    def __init__(self,length,atleast):
        self.length = length
        self.atleast = atleast
def main():
    try:
        s = input('请输入--->')
        if len(s) < 3:
            raise ShortInputException(len(s),3)
            
    except ShortInputException as result:
        print(result.length,result.atleast)
        
    else:
        print('没有异常发生')
    
main()




生成器

通过列表生成式,我们可以直接创建一个列表。但是,受到内存限制,列表容量肯定是有限的。

而且,创建一个包含100万个元素的列表,不仅占用很大的存储空间,如果我们仅仅需要访问前面几个元素,

那后面绝大多数元素占用的空间都白白浪费了。

所以,如果列表元素可以按照某种算法推算出来,那我们是否可以在循环的过程中不断推算出后续的元素呢?

这样就不必创建完整的list,从而节省大量的空间。在Python中,这种一边循环一边计算的机制,

称为生成器:generator。

创建生成器

迭代器

迭代:

访问集合元素的一种方式。

迭代器:

是一个可以记住遍历的位置的对象。

迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。

迭代器的特点:

迭代器只能往前不会后退。

迭代对象

以直接作用于 for 循环的数据类型有以下几种:

一类是集合数据类型,如 list 、 tuple 、 dict 、 set 、 str 等;

一类是 generator ,包括生成器和带 yield 的generator function。

这些可以直接作用于 for 循环的对象统称为可迭代对象: Iterable 。

from collections import Iterable
a = isinstance([],Iterable)
b = isinstance({},Iterable)
c = isinstance('abc',Iterable)
d = isinstance(100,Iterable)
e = isinstance((x for x in range(10)),Iterable)

print(a)
print(b)
print(c)
print(d)
print(e)


from collections import Iterator
a = isinstance(iter([]),Iterator)
b = isinstance({},Iterator)
c = isinstance('abc',Iterator)
d = isinstance(100,Iterator)
e = isinstance((x for x in range(10)),Iterator)

print(a)
print(b)
print(c)
print(d)
print(e)
迭代器使用
iter()函数
"""
1.凡是可作用于 for 循环的对象都是 Iterable 类型;
2.凡是可作用于 next() 函数的对象都是 Iterator 类型
3.集合数据类型如 list 、 dict 、 str 等是 Iterable 但不是 Iterator ,
不过可以通过 iter() 函数获得一个 Iterator 对象。
"""

装饰器

装饰器是程序开发中经常会用到的一个功能,用好了装饰器,开发效率如虎添翼,所以这也是Python面试中必问的问题,但对于好多初次接触这个知识的人来讲,这个功能有点绕,自学时直接绕过去了,然后面试问到了就挂了,因为装饰器是程序开发的基础知识,这个都不会,别跟人家说你会Python, 看了下面的文章,保证你学会装饰器。

#首先要先搞明白下面的代码:

#第一波 
def foo():
    print('foo')

foo     #表示是函数
foo()   #表示执行foo函数

#第二波
def foo():
    print('foo')

foo = lambda x: x + 1

foo(1)   # 执行下面的lambda表达式,而不再是原来的foo函数,因为foo这个名字被重新指向了另外一个匿名函数

def func1():
    print("haha")

def outer(func):
    def inner():
        print("*******************")
        func()
    return inner
#f是函数func1的加强版本
f = outer(func1)
f()
#如何理解装饰器
#需求:
#一个企业有N个业务部门,1个基础平台部门,基础平台负责提供底层的功能,
############### 基础平台提供的功能如下 ###############
def f1():
    print('f1')

def f2():
    print('f2')

def f3():
    print('f3')

def f4():
    print('f4')

############### 业务部门A 调用基础平台提供的功能 ###############

f1()
f2()
f3()
f4()

############### 业务部门B 调用基础平台提供的功能 ###############

f1()
f2()
f3()
f4()



#第一版
############### 基础平台提供的功能如下 ############### 

def f1():
    # 验证1
    # 验证2
    # 验证3
    print('f1')

def f2():
    # 验证1
    # 验证2
    # 验证3
    print('f2')

def f3():
    # 验证1
    # 验证2
    # 验证3
    print('f3')

def f4():
    # 验证1
    # 验证2
    # 验证3
    print('f4')

############### 业务部门不变 ############### 
### 业务部门A 调用基础平台提供的功能### 

f1()
f2()
f3()
f4()

### 业务部门B 调用基础平台提供的功能 ### 

f1()
f2()
f3()
f4()


#第二版
############### 基础平台提供的功能如下 ############### 

def check_login():
    # 验证1
    # 验证2
    # 验证3
    pass


def f1():

    check_login()

    print('f1')

def f2():

    check_login()

    print('f2')

def f3():

    check_login()

    print('f3')

def f4():

    check_login()

    print('f4')

    
#第三版
def w1(func):
    def inner():
        # 验证1
        # 验证2
        # 验证3
        func()
    return inner

@w1
def f1():
    print('f1')
@w1
def f2():
    print('f2')
@w1
def f3():
    print('f3')
@w1
def f4():
    print('f4')

    

#装饰器的基本使用

#定义函数:完成包裹数据
def makeBold(fn):
    def wrapped():
        return "<b>" + fn() + "</b>"
    return wrapped

#定义函数:完成包裹数据
def makeItalic(fn):
    def wrapped():
        return "<i>" + fn() + "</i>"
    return wrapped

@makeBold
def test1():
    return "hello world-1"

@makeItalic
def test2():
    return "hello world-2"

@makeBold
@makeItalic
def test3():
    return "hello world-3"

print(test1())
print(test2())
print(test3())
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值