装饰器、包的导入

python2 存在内存里的 字符串就是bytes,bytes就是字符串, 需要先解码(decode),再编码(encode)

python3 字符串 = unicode, bytes = py2 bytes, 不需要解码,自动转成unicode编码(没有decode方法) 如果需要转成别的格式,可以加上encode 默认文件编码utf-8, 变量的编码unicode

二进制--> bytes --> 字符编码的格式

一、为什么使用函数之模块化程序设计

不使用模块的缺点:

  1. 体系结构不清晰,可读性差
  2. 可扩展性差
  3. 程序冗长

二、定义函数

def func(args):
		‘‘‘文档描述‘‘‘
		函数体
		return 返回值

1. 无参函数
	def foo():
		print(‘in the foo‘)
	foo()

2. 有参函数
	def bar(x,y):
		print(‘in the bar‘)
	bar(1,2)

3. 定义空函数
	def func():
		pass

三、调用函数

1. 语句形式:类似无参函数
2. 表达式的形式
	def my_max(x,y):
		if x>y:
			return x
		else:return y
	res=my_max(1,2) # 语句形式
	res1 = 10*my_max(1,2) # 表达式形式

3. 作为另一个函数的参数
	my_max(1,my_max(2,3))

四、返回值

1. 不定义返回值,返回none
2. 返回一个
	def foo():
		return 1
	res=foo()
	print(res)

3. 返回多个
	def foo():
		return 1,‘s‘,[2,3]
	res=foo()
	print(res)
	#返回元祖形式

五、函数的参数

1、形参

def func(x,y):
	print(x)
	print(y)

2、实参

func(1,2)

3、从实参的角度

def foo(x,y):
    print(x,y)

foo(1,2) # 按位置传参
foo(y=10,x=‘a‘) # 按照key=value关键字形式

# 针对同一个形参,必须采用按位置或关键字为形参传值
# 按照位置
foo(y=2,1) # 错误

4、从形参的角度:位置参数,默认参数,可变长参数,**kwargs

def foo(x,y,z): # 位置参数:必传值参数
	print(x,y,z)
foo(y=2,x=1,z=3)

def foo(x,y=3): # 默认参数,定义的参数放在未定义参数后面
	print(x,y)
foo(1) # 打印 1 3

5、可变长参数 *args

# 实参按照位置
def foo(x,y,*args):
	print(x)
	print(y)
	print(args)
#1
foo(1,2,3,4,5,6,7)
#2
l=[3,4,5]
foo(1,2,*l) # 带*的方式

def foo(x,**kwargs):
	print(x)
	print(kwargs)
foo(1,y=3,z=1) # 不能对同一个形参赋值,如再加一个x=2
		dic = {‘a‘:1,‘b‘:2}
		foo(1,**dic)

		def foo(x,y,z):
			print(x,y,z)
		foo(**{‘x‘:1,‘z‘:3,‘y‘:2}) # foo(x=1,y=2,z=3) key要对应形参

# 位置参数 --> 默认参数,*args,**kwargs
# *args 等同于 展开按照位置的方式
# **kwargs 等同于 把kwargs展开按照关键字的方式

六、闭包函数

def page(url):
	def get():
		pass
	return get

装饰器

在遵循下面两个原则的前提下为被修饰者添加新功能,必须遵循两个原则:

  1. 一定不能修改源代码
  2. 不能修改调用方式

假设为index功能添加一个统计时间的功能

@timer # index=timer(index)
def index():
    print(‘in the index‘)

index()

# func1=deco1(index) --> func2=doco2(func1) --> func3=doco3(func2)
# 独立一行,从下往上调用
@deco3
@deco2
@deco1
def index():
    print(‘in the index‘)

index() # 最后调用deco3

用例

import time
def timer(func): # 只能一个参数,并且是被装饰的函数
    def wrapper():
        start_time = time.time()
        func() # 运行原始的index
        time.sleep(3)
        stop_time = time.time()
        print(‘run time is %s‘     %(stop_time-start_time))
    return wrapper

@timer
def index():
    print(‘in the index‘)
index()
# 这个用例中,没有改变index函数的代码及调用方式

无参装饰器

import time
import functools
def timer(func):
    @functools.wraps(func)
    def wrapper(*args,**kwargs): # ‘tom‘,23 --> (‘tom‘),{‘age‘:23}
        ‘‘‘
        wrapper func
        :param args:
        :param kwargs:
        :return:
        ‘‘‘
        start_time = time.time()
        # func() # 运行原始的index
        res=func(*args,**kwargs)
        # time.sleep(3)
        stop_time = time.time()
        print(‘run time is %s‘ %(stop_time-start_time))
        return res
    return wrapper
@timer
def index(msg):
    ‘‘‘
    index func
    :param msg:
    :return:
    ‘‘‘
    print(‘in the index‘,msg)
index(‘hello world‘)
@timer
def home(user,age):
     print(‘%s is %s years old‘ %(user,age))
    return 1
res = home(‘tom‘,age=23)
print(res)
print(help(index))

练习登陆官网

def auth(func):
    def login():
        un = ‘tommy‘
        pw = ‘anyway‘
        while 1:
            username = input(‘username>>: ‘).strip()
            passwd = input(‘password>>: ‘).strip()
            if username == un and passwd == pw:
                print(‘welcome to oldboy,‘, username)
                res = func()
                return res
            if username == ‘quit‘:
                break
    return login

@auth
def wel():
    print(‘官网,‘.center(20,‘-‘))
    return 1

welcome = wel()
print(welcome)

模块

import spa
print(spa.money)
spa.mo()

第一次导入模块做了三件事

  1. 创建新的作用域
  2. 在该作用域内执行顶级代码
  3. 得到一个模块名,绑定到该模块内的代码

为模块起别名

import spa as sp
print(sp.money)

一行导入多个

import re,os

from ... import...

from spa import mo
mo(5)

from ... import ... as ...

from spa import mo as m

from ... import *

spa文件中有:
__all__ = [‘mo‘,‘haha‘] # * 调用时只允许调用列表里的模块
另一个脚本调用时:
from spa import * # 下划线开头的无法被*导入
print(mo(10))
print(haha())
print(_change()) # name ‘_change‘ is not defined
print(bacc()) # 因为spa里定义了只允许调用的模块,这个会报错

导入模块顺序

  1. 内置函数(built-in)
  2. sys.path
  3. 附加函数

在sys.path中添加自定义目录

import sys
sys.path.insert(0,‘test_dir‘)

包的导入

import glance.db.models as db_model
db_model.register_models(‘mysql‘)

from glance.db.models import register_models
register_models(‘MySQL‘)

from glance.api import *
# 先导glace的init文件
# 再导api的init文件

绝对导入

from glance.db import models

相对导入

#在cmd目录程序中导入db目录的模块
from ..db import models

关于__name__

print(__name__)
# 把文件当作脚本执行__name__等于‘__main__‘
# 把文件spa.py当作模块去使用__name__等于模块名‘spa‘

if __name__ == ‘__main__‘:
    print(‘文件被当作脚本执行时触发的代码‘)
时间: 2024-10-13 00:18:32

装饰器、包的导入的相关文章

python 装饰器和property

一.  理解和实现装饰器 所谓装饰器, 就是在代码执行期间, 在不改变原有代码(类或者函数)的情况下, 为之动态附加功能. 例如, 在调用函数之前做一些计算, 在函数调用之后输出日志. 如何实现一个装饰器呢, 这里就需要使用到前面学习的知识闭包函数了. 1. 装饰器的原型 import time def decorator(func): # 将原函数作为参数传入 def newfunc(): # 调用之前 stime = time.perf_counter() func() # 调用原函数 #

Django视图函数函数之视图装饰器

FBV模式装饰器: 普通函数的装饰器(语法糖@) views.py 1 from django.shortcuts import render 2 3 def wrapper(f): 4 def inner(*args,**kwargs): 5 print("before") 6 ret=f(*args,**kwargs) 7 print("after") 8 return ret 9 return inner 10 11 @wrapper 12 def index

回顾Python装饰器

函数装饰器(function decorator)可以对函数进行“标注”,给函数提供更多的特性. 在理解装饰器之前需要理解闭包(closure).Python3.0 引入了保留关键字 nonlocal,使用闭包同样也离不开 nonlocal.顺便说一句,闭包除了用在装饰器上,对于异步编程也是很重要的概念. 装饰器(decorator)是一个可调用的装饰函数,它接收另一个函数作为参数. 假设已经定义好了一个装饰器 decorate(decorate 实际上是一个接收函数并且返回函数的函数),那么以

Python_day4 装饰器,模块倒入,包的导入

一.装饰器 1.什么是装饰器. 装饰器即函数 装饰即修饰,意指为其他函数添加新功能 装饰器定义:本质就是函数,功能是为其他函数添加新功能 2.装饰器需要遵循的原则. 1.不修改被装饰函数的源代码(开放封闭原则) 2.为被装饰函数添加新功能后,不修改被修饰函数的调用方式 3.装饰器的实现本质. 装饰器=高阶函数+函数嵌套+闭包 4.高阶函数 高阶函数定义: 1.函数接收的参数是一个函数名 2.函数的返回值是一个函数名 3.满足上述条件任意一个,都可称之为高阶函数 高阶函数示范: def foo()

尝试自己的Perl语言的包 TCP协议的再包装起到类似python语言装饰器的效果

#!/usr/bin/perl # Filename: BuildSocketTCP.pm # #   Copyright 2012 Axxeo GmbH #   Licensed under the Apache License, Version 2.0 (the "License"); #   you may not use this file except in compliance with the License. #   You may obtain a copy of t

尝试自己的Perl语言的包 UDP协议的再包装起到类似python语言装饰器的效果

#!/usr/bin/perl # Filename: BuildSocketUDP.pm # #   Copyright 2012 Axxeo GmbH #   Licensed under the Apache License, Version 2.0 (the "License"); #   you may not use this file except in compliance with the License. #   You may obtain a copy of t

遥想大肠包小肠----python装饰器乱弹

说起装饰器就tm蛋疼,在老男孩学习python装饰器,结果第二天默写,全错了,一道题抄十遍,共计二十遍. 要是装饰器是一人,我非要约他在必图拳馆来一场...... 下面容我展示一下默写二十遍的成果 语法形式 def  mydec(wenwa): def inner(*args,**kwagrs): ret = wenwa(*args,**kwargs) return ret  #请务必别忘记这还有个该死的return,如果被执行的函数没有返回值return,则ret为None return in

python----------闭包 、装饰器

闭包: 就是内层函数对外层函数(非全局变量的)非全局变量的引用 def func(): name = '老人家' def func1(): print(name)#局部变量对全局变量的引用 因为并没有在这个函数总定义name只是在它的父级定义了 return func1 func()() 闭包函数: 内部函数包含对外部作用域而非全剧作用域变量的引用,该内部函数称为闭包函数#函数内部定义的函数称为内部函数 为什么使用闭包: 闭包的使用就是开辟一个不是立刻关闭的空间 因为我们的函数每当执行完就会关闭

day10-闭包函数、函数装饰器

 一 什么是闭包? 闭包函数: 闭指的是:该函数是一个内部函数 包指的是:指的是该函数包含对外部作用域(非全局作用域)名字的引用 二 闭包的意义与应用 内部函数包含对外部作用域而非全局作用域的引用 提示:之前我们都是通过参数将外部的值传给函数,闭包提供了另外一种思路 def counter(): n=0 def incr(): nonlocal n x=n n+=1 return x return incr c=counter() print(c()) print(c()) print(c())