pyhton_学习笔记0804

来源:互联网 发布:淘宝冻结账户怎么解冻 编辑:程序博客网 时间:2024/06/05 16:15

今日是二零一伍年八月四日

1.关于python中的set,其实它非常像c语言中的set ,是纯键值储存。和dict一样,容器符号是{ }。

s = {1 , 2 , 3 , 4}

同样可以借助一个list定义

# set.pyl = [1 , 2 , 3 , 4]s = set(l)print(s)
可以使用add()和remove()函数添加和减去键值,也可以通过二元运算符& 、|  对两个set运算


2.对于不变对象来说,调用对象自身的任意方法,也不会改变该对象自身的内容。相反,这些方法会创建新的对象并返回,这样,就保证了不可变对象本身永远是不可变的。


3.在python中,函数的别名可以直接赋值

>>> a = abs # 变量a指向abs函数>>> a(-1) # 所以也可以通过a调用abs函数1


4.在python中,函数的定义只需要函数名、和参数,不需要返回类型和参数类型

# func.pydef my_abs(x) :    if x >= 0 :        return x    else :        return -x
不要忘记冒号


由于并没有参数类型的要求,在实际中,我们往往就需要参数检查。isinstance函数可以提供这样的帮助。

# func.pydef my_abs(x):if not isinstance(x , (float , int ) )  # 函数在x是要求的type时,返还trueraise TypeError('bad operand type')  # 抛出异常    if x >= 0:        return x    else:        return -x


5.在python中,函数可以尝试返还多个变量

# func.pydef go_forward (x , y) :x += 1 ; y += 1return x , y x1 = 2 ; y1 = 2 x1 , y1 = go_forward(x1 , y1 )print(x1 , y1)
结果是

3 3
当然,这其实是一种假象。函数其实还是只返还了一个值

# func.pydef go_forward ( x , y ) :x += 1 ; y += 1return x , y x1 = 2 ; y1 = 2 dot = go_forward( x1 , y1 )print( dot )<pre name="code" class="python">print str( type( dot ) )

结果是

(3,3)<pre name="code" class="python">(class 'tuple')

证明,函数在面临需要返还多个对象时,往往是把它们当做是tuple。而在调用时,函数会尝试给等号左边的变量依次赋值。

在语法上,返回一个tuple可以省略括号,而多个变量可以同时接收一个tuple,按位置赋给对应的值,所以,Python的函数返回多值其实就是返回一个tuple,但写起来更方便。

# tuple_test.pys = ( 1 ,2 )x , y = s print( x , y )
其结果为
1 2


6.关于函数的默认参数,python倒是有一个小陷阱

我们先来看一个例子

def func( x = 5 ) :    x += 1    print (x)func( )func( )
结果是

66
这个我想是肯定没问题的,那么再来

# func_parameter.pydef func( x = [] ) :    x.append( 2 )    print (x)func( )func( )
结果是

[2][2,2]
那么是为什么呢,我们来看一段python manual的说法

Default parameter values are evaluated when the function definition is executed. This means that the expression is evaluated once, when the function is defined, and that that same “pre-computed” value is used for each call. This is especially important to understand when a default parameter is a mutable object, such as a list or a dictionary: if the function modifies the object (e.g. by appending an item to a list), the default value is in effect modified. This is generally not what was intended. A way around this is to use None as the default, and explicitly test for it in the body of the function。

def whats_on_the_telly(penguin=None):    if penguin is None:        penguin = []    penguin.append("property of the zoo")    return penguin

我来翻译一下:

当函数的定义句柄被执行后,函数里的默认参数就被赋值了。这代表着,当函数被定义后,默认参数只会被赋值一次。之后的每一次函数调用,都会使用同一个变量。这就很容易理解,为什么当一个默认参数被设置成类似于list、dictionary这种可改变的对象时,如果函数尝试去修改这个对象,默认值也被修改了。这往往不是编程者所有意的。这个问题的解决办法之一就是,使用None作为我们的默认值。

解释也提供了一种十分常规的解决办法。


这是关于有默认值的函数的一些说明,可以这么理解,python中缺省参数和函数是绑定的。当一个函数有一个默认参数,并且默认参数是空的可变类型时(dict和list),该可变类型只初始化一次,之后的每次操作,都在前一次的操作基础上操作。但是对于默认参数是不可变的类型时(tuple和字符串和数字),不会有这种情况。


7.在python中,可以把list和tuple对象当做参数传递给函数体内部。在函数内部接受到的,是一个tuple。可以看一个例子

# func_list.pynums = [1 , 2 , 3]def calc( *numbers):numbers.append(4)print(numbers)return Nonecalc( * nums )print ( nums )
程序是无法执行的,报错是

Traceback (most recent call last):
  File "func_list.py", line 10, in <module>
    calc( * nums)
  File "func_list.py", line 6, in calc
    numbers.append(4)
AttributeError: 'tuple' object has no attribute 'append'

意思是,tuple无权调用append函数。这也证明,numbers是一个tuple。

同样的,在参数中使用**符号,便可以接收一个字典。比如:

>>>def person(name, age, **kw):...   print('name:', name, 'age:', age, 'other:', kw)>>>person('Adam', 45, gender='M', job='Engineer')name: Adam age: 45 other: {'gender': 'M', 'job': 'Engineer'}

**kw就作为一个参数接受了一个字典。这样的参数我们姑且称之为关键字参数。

还有一类叫做命名关键字参数。笔者其实至今不是很了解命名关键字参数的作用,只在这里做一个介绍。

def person(name, age, *, city, job):    print(name, age, city, job)
型如此类的参数传递便是命名关键字参数。*符号作为标识符,表示在此以后的参数都是命名关键字参数。命名关键字参数在调用时必须使用命名法,如:

>>> person('Jack', 24, city='Beijing', job='Engineer')
如果没有传递参数名,函数调用将是失败的。



8.在python中还提供了一种参数传递的方法,就是在传递变量时,指定好传递对象。

# func_para.pydef test( x , y ) :print(' x =' , x )print(' y =' , y , '\n' )return Nonetest( 1 , 2 )test( x = 2 , y = 1 )
结果是

 x = 1 y = 2 x = 2 y = 1
但是在c中

// func_parameter.cpp#include <iostream>using namespace std ;void func(int x , int y ){cout << 'x = ' << x << endl ;cout << 'y = ' << y << endl ;return ;}int main (){func(1 , 2) ;func (x = 2 , y = 1 ) ;return 0 ;}
是无法编译的。如此方便的传送方法也为python的函数调用提供便捷。
0 0
原创粉丝点击