python基础编程: 函数示例、装饰器、模块、内置函数

目录:

  1. 函数示例
  2. 装饰器
  3. 模块
  4. 内置函数

一、函数示例:

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

    不使用模块程序设计的缺点:
    1、体系结构不清晰,可主读性差;
    2、可扩展性差;
    3、程序冗长;

  2、定义函数:
    def fun(args):
      '描述信息'
      函数体
    return 返回值

  定义函数的三种形式:
    无参函数

def foo():
    print('in the foo')

foo() 

有参函数:

def bar(x,y):
    print('in the bar')

bar(1,2)

空函数:

def func():
    pass

空函数的应用示例:

def put():
    pass

def get():
    pass

def cd():
    pass

def ls():
    pass

def auth():
    pass

3、调用函数:
三种形式:
语句形式:

def foo():
    print('in the foo')

foo()

表达式形式:

def my_max(x,y)
    if x>y:
        return x
    else:
        return y

res = my_max(1,2)
res = 10 * my_max(1,2)   
作为另外一个函数的参数:
my_max(1,my_max(2,3)): #先比较2与3的最大值,再与1作比较;    

4、函数的返回值三种形式:
不返回函数:

def foo():
    print('in the foo')

res = foo()
print(res)

返回一个函数:

def foo():
    return 1
res = foo()
print(res)

返回多个:

def foo():
    return 1,'s',[1,2,3]

res = foo()
print(res)

5、函数的参数:

def func(x,y): #形参在调用时才真正占用内存空间,调用结束则释放内存空间;
    print(x)
    print(y)

fund(1,2) #实参真实占用内存空间;


def func(x,y):
    if type(x) is int and type(y) is int:
    return x+y

func(1,'a')

def func(x,y): #使用文档注释来提醒用户输入参数类型;
    '''
    '''
    return x+y

func(1,'a')


def func(x:int,y:int)->int: #只是一个提示作用;
    pass
    print(func.__annotations__)

从实参的角度,
按位置传值:
def foo(x,y):
    print(x,y)
foo(1,2)

按关键字传参:key = value
def foo(x,y):
    print(x,y)
foo(y=2,x=1) #优点:不用按位置来输入参数;

针对同一个形参,要么按照位置要么按照关键字为形参传值;关键字参数必须写到位置参数的右边;
如:foo(1,x=1,y=2) 此方法会报错;

从形参的角度:位置参数,默认参数,可变长参数*args;**kwargs;
按位置定义的形参:
def foo(x,y,z): #位置参数;也就是必传值参数;
    print(x)
    print(y)
    print(z)

foo(1,2,3)
foo(y=2,x=1,z=3)

按默认参数的形参:
def foo(x,y=1): #y就是默认参数;但也可以去赋值;默认参数建议不要使用列表或字典等可变类型;必须放在默认参数之后;
    print(x)
    print(y)
foo(1)

按可变长参数的形参:
def foo(x,y=1,*args): #可变长参数必须放在位置参数与默认参数的后面;此情况一般不使用位置参数;
    print(x)
    print(y)
    print(args)

foo(1,2,3,4,54,6,3,y=2) #错
foo(1,2,3,4,54,y=2,3,5) #错
foo(1,2,3,4,54,6,3) #对


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

l=['a','b']
foo(1,2,*1) #*args的形式就等于1,2,3,4,5 解包;

('a','b')

 

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

# foo(1,2,3)
l=[1,2,3]
foo(*l)


def foo(x,**kwargs):
    print(x)
    print(kwargs)

foo(1,y=3,z=2)
dic = {'a':1,'b':2}
foo(1,**dic) #foo(1,a=1,b=2)

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

foo(**{'a':1,'b':2,'c':3}) #foo(a=1,b=2,c=3),要把a,b,c改成x,y,z
foo(**{'x':1,'y':2,'z':3})

注:位置参数 -> 默认参数,*args, **kwargs
1、*args 相当于展开按照位置的方式去写;
2、**kwargs 相当于把kwargs按照关键字的方式去写;

6、函数是第一类对象的意思就是函数可以被当作数据来传递;

def func()
    print('in the fun')

fl = fun
fl()

函数可作为参数:高阶函数:
def foo(x):
    x()
foo(func)

返回值可以是函数:
##########################################

可以作为容器类型的元素:
func_dic={
    'func':func
}

func_diuc['func']()

7、函数的嵌套:分为两种:

嵌套的调用:
def my_max1(a,b,c,d):
    res1=my_max(a,b)
    res2=my_max(res1,c)
    res3=my_max(res2,d)
    return res3

def my_max(x,y):
    if x > y:
        return x
    else:
        return y

print(my_max1(100,2,-1,5))
嵌套的定义: python支持静态的嵌套域;
x=1
def f1():
    def f2():
        print(x)
#def f3():
#	print(x)
#return f3	
    return f2

f2=f1()

闭包函数:
def f1():
    x=1
    def f2():
        print(x)
    return f2

f = f1()
f()

示例:
from urllib request import urlopen #用来爬网页;
def page(url):
    def get():
        return urlopen(url).read()
    return get

baidu = page('http//ww.baidu.com')
python = page('http://www.python.org')
baidu()

二、装饰器

装饰器:在遵循下面的两个原则 的前提下为被修饰者添加新功能;
函数功能的扩展原则:
1、一定不能修改源代码;
2、不能改变函数的调用方式;

装饰器本身是一个函数,被装饰的也是一个函数;

示例:

def index():
print('in the ndex')
index()

@timer #表示方法:index = timer(index)
def index():
print('in the ndex')
index()

装饰器的叠加:
@deco3
@deco2
@deco1 #func1 = deco1(index) --> func2=deco2(func1) --> index= deco3(func2)====>index=deco3(deco2(deco1(index)))
def index():
print('in the ndex')
index()

示例:
from urllib request import urlopen #用来爬网页;
import time
def timer(func):
def wrapper():
print('in the wrapper-->start')
start_time=time.time()
func()
print('in the wrapper-->stop')
return wrapper

@timer #表示方法:index = timer(index)
def index():
print('in the ndex')
index()

 

from urllib request import urlopen #用来爬网页;
import time
def timer(func):
    def wrapper(*args,**kwargs): #一定不要写死;
        print('in the wrapper-->start')
        start_time=time.time()
        res=func(*args,**kwargs) #home('tom',msg='xxxx')-->home(user,msg) *与位置等同
        func(msg) #运行最原始的index -> index(msg)
        print('in the wrapper-->stop')
        return res
        return wrapper

@timer #表示方法:index = timer(index)
def index(msg):
    print('in the ndex',msg)

@timer
def home(user,msg):
    print('in the home %s %s',%(user,msg)
    return 1 #返回值要写在wrapper中


index('hello world')
home('tom',msg='xxxx')

三、模块

什么是模块:
模块就是一个包含了python定义和声明的文件;文件名就是模块名字加上.py的后缀;

模块只会被导入一次,第一次会导入到内存中,第二次再导入直接去内存调用

模块的导入:
第一次导入模块三个事件:
1、创建新的作用域;
2、在该作用域内执行顶级代码;
3、得到一个模块名,绑定到该模块内的代码;

为模块起别名:
import spam as sm
    print(sm.money)
from spam import read1 as rea


导入多个模块:
import ms,spam,re
from spam import (read1,change)可写入多行;


导入模块的另外一种形式:
from .. import ..
from spam import read1
read1()

总结:
从那来就从哪执行,与调用的位置无关;

将module中所有非下划线开头的名称导入:
from module import *
__all__ = ['money','read1']

注:
模块不支持重载;要加载需要重启程序;

把文件当做和脚本执行__name__等于'__main__';
print(__name__)
把spam.py文件当作模块去使用__name__等于'spam'


if __name__ = '__main__':
    print('文件被当作脚本执行时触发的代码')


可以控制python代码在不同场景下运行的代码;

模块路径的查找:
import sys
sys.path
路径的查找先找内置的路径,再找其他的路径;
来源:
1、当前目录;
2、python path
3、安装时依赖的一些目录;

sys.path.append(r'/test') #当前目录有效;
r表示对特殊字符的转义;
sys.path.insert(0,r'/test') #从0的位置插入;

导入模块时,先从内建中找相同的模块名,找不到就去sys.path中找;

dir()
不会列举出内建模块的名字;
import builtins
dir(builtins)


包:
包是一种通过使用‘.模块名’来组织python模块名称空间的方式。

无论是import形式还是from...import形式,凡是在导入语句中(而不是在使用时)遇到带点的,都要第一时间提高警觉:这是关于包才有的导入语法

包的本质就是一个包含__init__.py文件的目录。

from ... import ...

需要注意的是from后import导入的模块,必须是明确的一个不能带点,否则会有语法错误,如:from a import b.c是错误语法

__init__.py文件

不管是哪种方式,只要是第一次导入包或者是包的任何其他部分,都会依次执行包下的__init__.py文件(我们可以在每个包的文件内都打印一行内容来验证一下),这个文件可以为空,但是也可以存放一些初始化包的代码。


from glance.api import *

在讲模块时,我们已经讨论过了从一个模块内导入所有*,此处我们研究从一个包导入所有*。

此处是想从包api中导入所有,实际上该语句只会导入包api下__init__.py文件中定义的名字,我们可以在这个文件中定义__all___:

 #在__init__.py中定义
 x=10

 def func():
     print('from api.__init.py')
 
 __all__=['x','func','policy']

此时我们在于glance同级的文件中执行from glance.api import *就导入__all__中的内容(versions仍然不能导入)。

示例:

from glance.api import *
只会运行api下的__init__.py文件;


在api\__init__.py中输入:
__all__ = ['policy','versions']



import只能导入内建与第三方的模块,否则会出错;

四、内置函数

内置函数解释:

# !/usr/bin/env python
# -*- coding:utf-8 -*-

#返回数字的绝对值。 参数可以是整数或浮点数。 如果参数是复数,则返回其大小。
print(abs(-1.11))

#传入一个可被循环的元素,如果这个元素中有一个为False则都为假
# 0 空值 False 都为假
print(all([1,2,3]))

#与all相反,只有一个为真,则为真;
print(any([0,2,False]))

#这个函数跟repr()函数一样,返回一个可打印的对象字符串方式表示。当遇到非ASCII码时
#就会输出x,u或U等字符来表示。与Python 2版本里的repr()是等效的函数。
print(ascii("dsads"),ascii(66),ascii('b23'))

#将十进制转换为二进制;
print(bin(10))

#返回布尔值,即True或False之一,如果参数为false或省略,则返回False; 否则返回True。
print(bool(1))

#根据传入的参数创建一个新的字节数组
#如果传入字符串必须给出编码
print(bytearray('你好','utf-8'))
#当source参数是一个可迭代对象,那么这个对象中的元素必须符合大于0 小于256
print(bytearray([256,1,2]))

#返回一个的“bytes”对象,返回bytes类型
bytes('中文','utf-8')

#检查对象是否可以被调用
def func():
    pass
print(callable(func))

#返回整数所对应的Unicode字符,chr(97)返回字符串'a',而chr(8364)返回字符串'€'。
print(chr(126))

#是用来指定一个类的方法为类方法,类方法可以不实例化直接调用
class A:
    @classmethod
    def B(cls,arg1,):
        print(arg1)
A.B(1)
A().B(1)

#将源编译为代码或者AST对象。代码对象能够通过exec语句来执行或者eval()进行求值。
#源可以是正常字符串,字节字符串或AST对象。
expr = "5+5-1"
obj = compile(expr,"","eval")
print(eval(obj))

#返回值为real + imag * j的复数或者转化一个字符串或数为复数。如果第一个参数为字符串,则不需要指定第二个参数。
print(complex(1, 2))
print(complex(1))
print(complex("1+2j"))



# 参数是一个对象和一个字符串。 该字符串必须是对象属性之一的名称。
class A:
    def a1(self):
        print("a1")
    def a2(self):
        print("a2")

obj = A
print(dir(obj))
delattr(obj, "a1")
print(dir(obj))

#dir 返回对象中的方法
strs="aaa"
print(dir(strs))

#返回两个数值的商和余数
print(divmod(7,3))

#用于遍历序列中的元素以及它们的下标
print(enumerate([1,2,3]))#返回的是可迭代的对象
for i,j in enumerate(('A','B','C')):
    print(i,j)

#将字符串str当成有效的表达式来求值并返回计算结果。
print(eval("1+2+3"))
print(eval("False or True"))

#字符串str当成动态语句块执行并返回结果
exec('a=1+2+3')
print(a)

#使用指定方法(方法,函数),过滤可迭代对象的元素
def add(arg):
    return arg > 3

for i in filter(add,[1,2,3,4,5]):
    print(i)

#浮点型
print(float(11))

#格式化显示 更多方法请参考官方说明
print('{:,.2f}'.format(111111))

#根据传入的参数创建一个新的不可变集合
a = frozenset([1,2,3,4,5])
print(a)

#获取对象的属性值
class A():
    def __init__(self,):
        self.name = "123"
b = A()
print(getattr(b,'name'))

#返回当前作用域内的全局变量和其值组成的字典
print(globals())

#检查对象是否含有属性
class A():
    def __init__(self,):
        self.name = "123"
b = A()
print(hasattr(b,'name'))

#哈希值计算
#在当前环境中是唯一的
print(hash('Hello'))

#help帮助
def funcs(args):
    """
    Function description
    :param args: args = list
    :return:
    """
    pass
print(help(funcs))

#转换16进制
print(hex(44))

#显示对象的标识符
print(id("123"))

#input标准输入
s = input("user name:")
print(s)

#int返回整数
print(int(1.2))
print(int("2"))

#判断对象是否是类或者类型元组中任意类元素的实例
print(isinstance("1",int))
print(isinstance(1.1,(int,float)))


#判断类是否是另外一个类或者类型元组中任意类元素的子类
print(dir(str))
print(issubclass(bytearray,str))
print(issubclass(bool,int))

#根据传入的参数创建一个新的可迭代对象
a = iter('12345')
print(next(a))
print(next(a))

#返回对象的长度len
a = [1,2,3,4]

#转换列表
print(list("abcd"))

#返回当前作用域内的局部变量和其值组成的字典
def A():
    print(locals())
    s = 1
    print(locals())
A()

#使用指定方法去作用传入的每个可迭代对象的元素,生成新的可迭代对象
def add(x):
    return x+100
lists = [1,2,3,4]
for i in map(add,lists):
    print(i)

#max:返回最大值
print(max(1,2,3))
print(max([1,2,3,4]))

#在进行切片并赋值数据时,不需要重新copy原列表数据,可以直接映射原数据内存;
s = memoryview(b'abcd')
print(s[1])

#返回最小值
print(min(1,2,3))
print(min([2,3]))

#返回可迭代对象中的下一个元素值
a = iter('1234')
print(next(a))

#创建一个新的object对象(新式类)
class B(object):
    pass

#转化成8进制数字符串
print(oct(10))

#open文件操作
file = open('test.txt',encoding="utf-8")

#ord:返回Unicode字符对应的整数
print(ord("A"))

#幂运算

print(pow(2,3))

#标准输出
print()

#property:标示属性的装饰器
#类中使用具体方法请百度,或者等待后续更新
property

#range:根据传入的参数创建一个新的range对象
range(10)
range(1,10)

"""repr()函数得到的字符串通常可以用来重新获得该对象,repr()的输入对python比较友好。
通常情况下obj==eval(repr(obj))这个等式是成立的。"""
obj='Python'
print(eval(repr(obj)))


#翻转序列
a = reversed([1,2,3,4,5])
print(list(a))

#round:对浮点数进行四舍五入求值
print(round(1.5))

#set 转换成集合
print(set([1,2,3]))

#setattr:设置对象的属性值
class A():
    def __init__(self,age):
        self.age = age
s = A(11)
print(s.age)
setattr(s,'age',22)
print(s.age)

#根据传入的参数创建一个新的切片对象
c1 = slice(3)
c2 = slice(2,4)
c3 = slice(0,5,2)
s = [1,2,3,4,5,6]
print(s[c1])
print(s[c2])
print(s[c3])


#排序,返回一个新的列表默认按字符ascii码排序
a = [4,3,2,1,7]
print(sorted(a))

#标示方法为静态方法的装饰器
class B(object):
    def __init__(self,age):
        self.age = age

    @staticmethod
    def hello(args):
        print(args)

B.hello("Hello World")

#字符串类型
print(str(123))

#求和
print(sum([1,2,3,4]))

#根据传入的参数创建一个新的子类和父类关系的代理对象
class A(object):
    def __init__(self):
        print("我是 A Clase")

class B(A):
    def __init__(self):
        print("我是 B Class")
        super().__init__()
b = B()

#元祖
tuple([1,2,3,4])


#type 返回对象的类型
print(type([1]))
print(type("1"))

#返回当前作用域内的局部变量和其值组成的字典,或者返回对象的属性列表
def func():
    print(vars())
    s = 1
    print(vars())
func()

#聚合传入的每个迭代器中相同位置的元素,返回一个新的元组类型迭代器
list1 = [1,2,3]
list2 = ["A","B","C","D"]
print(zip(list1,list2))
for i in zip(list1,list2):
    print(i)

#__import__:动态导入模块
__import__

  

  

原文地址:https://www.cnblogs.com/hsggj/p/6402808.html