函数基础语法
(1)有用的内置函数
dir()
help()
isinstance(obj,string/iterable) ,判断变量所引用的对象的数据类型
(2)return只能用在函数里。
Return 没有返回语言返回一些对象,后面的函数调用他时,处理时很可能就会报错
# return out of function 报错提示
(3)Def func():
Pass
和什么都不写,有什么区别??占位而已,有些时候不写不行就写一个pass暂时
关于高级函数
我的想法,先都按低级基础的方法写一遍
然后才能体会到高级方法的好处!!!
练习需要勤动手
一 函数,脚本,变量的类比
函数的本质:一段代码块
准确的说是:一段有名字的代码块
用名字就可以代替block,被调用
实际上,模块等同理
function:定义一个代码段block,命名为函数名,可以接受参数(var)
方法:变量的函数是方法 var.func()
script: 定义一个整个代码---代码文件,命名为脚本文件名,可接受参数argv,
var: 定义一个变量,命名为变量名,
module: 一个定义好的大段代码文件?比script更大?
二 函数带参数调用尝试
print 函数好像所有的内容只打印1次,如果之前打印了某几行,打印全部的时候的,那几行就不再被打印?
.readline() 据说是读的光标处的1行,连续的读,光标会随之移动,所以连续调用.readline()就显得像逐行打印一样的效果
# -*- coding:utf-8 -*-
#函数
from sys import argv
script,input_file=argv
def print_func(f):
print(f.read())
def rewind(f):
f.seek(0)
def print_a_line(line_count,f):
print line_count,f.readline()
current_file=open(input_file)
print("let's print the whole file %s ") %input_file
print_func(current_file)
print("let's rewind")
rewind(current_file)
print current_file.readline()
print current_file.readline() #readline()看起来只是每输入一次,依次打第1行。。。而且打完不显示了
"""
print("let's print three lines")
current_line=1
print_a_line(current_line,current_file)
current_line=1+current_line
print_a_line(current_line,current_file)
current_line=1+current_line
print_a_line(current_line,current_file)
"""
三 理解:函数定义与函数调用
下面这个例子,是根据书上的稍微改写的
(1) python是解释型语言,脚本性,胶水性语言,不是C++那种编译性的语言,
是一边允许一边解释的,而没在运行的也就不会去解释。
所以函数的定义内def 内,除了语法错误,其他运行时才会体现的错误是不会被提前检查出来的
并且,理论上,def内的内容,可以认为都不算这个脚本:主程序的的一部分
(2)脚本的第1行实际可以认为是 print 另外就是主函数调用 start() 这两句,其他都是定义和被调用部分。
(3)现在 if or的用法还没搞清楚 ???
(4)现在还不熟悉,限制输入,或者规整输入,避免出错的方法?
现在就是用 if 判断不符合要求,末尾再调回函数开头,形成这样的强制循环
# -*- coding:utf-8 -*-
from sys import exit
def start():
print "you are now in a dark room"
print "on your right side is a red door"
print "on your left side is blue door"
print "make your choice:red or blue?"
user_choice=raw_input("you can only choose red or blue!>>")
if user_choice=="red": # "red" or "RED" 居然会导致选择都选前一支?
gold_room()
elif user_choice=="blue" : #好像有办法可以忽略大小写,判断blue字符
bear_room()
else:
print("you must make a choice")
start()
def dead(reason):
print reason,",haha good job ^ ^"
exit(0)
def gold_room():
print("this a big room full of golds,haha,but gold is too heavy to carry to much")
print("how much gold do you want to take?")
gold_take=raw_input("enter a numble>>")
if isinstance(int(gold_take),int): #判断数据类型int list dict
gold_take_num=int(gold_take) #当玩家数据类型输入不对,py本身会报错,这是个问题
else:
dead("man,you must first learn to type a numble!not others")
if gold_take_num<=999999:
print("you are lucky dog,take your gold and leave! ~ ~!")
else:
dead("you are too greedy,a snake in gold bite you to dead")
def bear_room():
print("woo... a big bear is in the room!")
print("what do you want to do?")
print "A beat the bear;B talk with the bear and try to make friends"
bear_chooice=raw_input("you can only enter A or B>>")
if bear_chooice=="A" or "a":
dead("how can you think you can fight a bear? the bear beat you to death!")
elif bear_chooice=="B" or "b":
print("lucky dog,the bear likes you ,you are friends now~ ^ ^ 666666")
else:
print("you can only enter A or B!")
bear_room()
print("now let us play a game")
start()
形式参数和实参
形参,形式参数:就是函数定义时的 参数样式, pack
只在函数内部有效,函数生命周期外都无法使用的
(部分)形参的变量名无所谓,不重要
实参/实际参数: 就是调用函数时,实际传入的变量名(对应着对象)
调用函数,传入参数的这个过程,称为解包函数?unpack
实参可以是 常量,变量,表达式,函数
函数与参数
参考资料
https://www.cnblogs.com/bingabcd/p/6671368.html
https://blog.csdn.net/u014745194/article/details/70158926
参数类型
(1)必选参数 / 位置参数 a,b ,必须按位置传进去
位置参数 position 按位置次序 对应解析 位置参数,个数也要相等,否则报错
F(3,2)
(2)可选参数 / 默认参数 c=0 可传可不传
默认参数,函数定义的时候写成def (x, y=2)
调用可以f(3,2)或者f(3)
(3)可变参数 *args 实际上是一个元组 tuple ()
(4)命名关键字参数 *, d 或 *args,d 参数名字限制必须是指定的名字
关键字参数:从函数看起来和位置参数一样,只是调用时,会写成
F(x=3,y=2)
会顺序无关,可以写成f (y=2,x=3)
(5)关键字参数 **kw **kargs 实际上是一个字典 dict ()
一般这2个*args 和 **kw,都用在闭包和装饰器里?
实际使用时有次序
格式1:def func1(a,b,c=0,*args,d,**kw) #若默认参数在*args前,如果没给默认参数赋值,会默认先给默认参数赋值
格式2:def func1(a,b,*args,c=0,d,**kw) #若默认参数在*args后,如果没给默认参数赋值,不会默认先给默认参数赋值
格式3:def func1(a,b,c=0,*,d,**kw) #若命名的关键字参数前,没有*args,那么得额外加一个 *,
>>> def func1(a,b,c=100,*args,name,nation,**kargs):
print(a,b,c,args,name,nation,kargs)
>>> def func2(a,b,*args,c=100,name,nation,**kargs):
print(a,b,c,args,name,nation,kargs)
>>> func1(1,5,*(9,9,9),name="john",nation="china",**{"class":1,"grade":2})
1 5 9 (9, 9) john china {'class': 1, 'grade': 2}
>>> func2(1,5,*(9,9,9),name="john",nation="china",**{"class":1,"grade":2})
1 5 100 (9, 9, 9) john china {'class': 1, 'grade': 2}
>>>
1 必选参数/位置参数 para1,para2
>>> def testfunc(a,b):
print(a,b)
>>> testfunc(1,2)
1 2
2 可选参数/默认参数(带有默认值,降低调用函数时出错的可能性) para=3
默认参数一定要是不可变对象 c=3 c="abc" int float string 等不可变对象
尽量不要是可变对象,容易以后出错 c=[1,2,3]
>>> def testfunc2(a,b,c=3):
print(a,b,c)
>>> testfunc2(5,6)
5 6 3
>>> testfunc2(5,6,7)
5 6 7
>>>
3 可变参数 *args (可以在 默认参数之前,根据具体需要)
(1) *args 的数量不定,也可以没有
(2)*args 可以在函数调用,unpack时,直接一个个传进去
(3)*args 也可以直接传入 tuple 或 list
但要记住list tupla 替代的只是args ,传进去的时候,是 *tuple *list
>>> def testfunc3(*args):
print(args)
>>> testfunc3(1,3,5)
(1, 3, 5)
>>> args=(1,3,5,7)
>>> listA=[5,6,7]
>>> tupleA=(7,8,9)
>>> testfunc3(*args)
(1, 3, 5, 7)
>>> testfunc3(*tupleA)
(7, 8, 9)
>>> testfunc3(*listA)
(5, 6, 7)
>>> funcA2(1,2,3)
(1, 2, 3)
>>> funcA2(*(4,5,6))
(4, 5, 6)
>>> tupleA2=(7,8,9)
>>> funcA2(*tupleA2)
(7, 8, 9)
错误的写法,这样写,实际上是位置参数
>>> testfunc3(args)
((1, 3, 5, 7),)
>>> testfunc3((7,8,9))
((7, 8, 9),)
>>> testfunc3(tupleA)
((7, 8, 9),)
>>> testfunc3(listA)
([5, 6, 7],)
4 命名的关键字参数
两种声明方式
func1(name, age, *args, city, job)
func2(name, age, *, city, job)
只要是放在这个*args, 或 * 之后的,就一定是 命名的关键字参数,如果不是,会被认为是必选参数
调用时,参数名字必须和这个定义的相同
5 关键字参数
关键字参数实际上是一个字典dict
>>> def func1(a,b,c=100,*args,name,nation,**kargs):
print(a,b,c,args,name,nation,kargs)
>>> def func2(a,b,*args,c=100,name,nation,**kargs):
print(a,b,c,args,name,nation,kargs)
>>> func1(1,5,*(9,9,9),name="john",nation="china",**{"class":1,"grade":2})
1 5 9 (9, 9) john china {'class': 1, 'grade': 2}
>>> func2(1,5,*(9,9,9),name="john",nation="china",**{"class":1,"grade":2})
1 5 100 (9, 9, 9) john china {'class': 1, 'grade': 2}
>>>
关键字参数可以直接用字典,或字典变量,
但是语法上得合规:
合规的dict写法 {"a":1,"b":2} e=5,f=6
不合规的dict写法 "g":5,"h":6 "g"=5,"h"=6
>>> funcA3(**{"a":1,"b":2})
{'a': 1, 'b': 2}
>>> dictA3={"c":3,"d":4}
>>> funcA3(**dictA3)
{'c': 3, 'd': 4}
>>> funcA3(e=5,f=6)
{'e': 5, 'f': 6}
>>> funcA3("g"=5,"h"=6)
SyntaxError: keyword can't be an expression
>>> funcA3("g":5,"h":6)
SyntaxError: invalid syntax
>>>
局部变量与全局变量
全局变量:
作用域在外部,
或者没局部变量的内部,
或者声明了global的内部(一般是为了修改?有可能只是为了,区别内部变量同名问题,只为了读外部变量吗?)
Global a 只能声明,不能同时赋值
局部变量:只在内部
(1)函数内部,优先是局部变量
(2)函数外部的全局变量,可以在函数内部使用
(3)函数内部可以用 global 定义全局变量
但这种不能同时赋值
SyntaxError: invalid syntax
>>> def funcB1():
a=3
>>> def funcB2():
global a
>>> def funcB3():
global a=3
SyntaxError: invalid syntax
在基本的python语法当中,一个函数可以随意读取全局数据,但是要修改全局数据的时候有两种方法:1 global 声明全局变量 2 全局变量是可变类型数据的时候可以修改
无论内部外部,声明全局变量时不能同时赋值
内部也可以定义 global a
内部变量 优先是局部变量
内部可以随便引用外部变量,但修改比较麻烦
基础概念辨析(没基础,所有概念还是仔细查了辨析吧,先备忘在这)
return : 不return的话,就会随着函数调用结束而消灭?
print :函数里加这个用处不大,因为主要是函数之间的调用
命令行还可以加这个,作为输出查看
函数与Return
- 函数一定有返回值,如果没有,默认为none
- return只能用在def 函数体内部
- return用于返回值,是为了返回函数执行的结果。
- 其中,函数式编程:返回值
- 而面向过程编程,一般没有返回值
- .函数在执行过程中碰到return语句,就会停止执行后面的代码并放回结果。
- 如果有一个返回值,则返回的是一个object
- 如果有多个返回值,则返回的是一个tuple