【原创】《笨办法学python》(4)--函数和参数

 

 

函数基础语法

(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

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值