python自学软件测试测试员的那点事

[Code] Python简单小知识

2018-01-23  本文已影响64人  敲代码的密斯想

1. Python函数参数

1. 位置参数

调用时根据定义参数的顺序传参,如下例:

def fun(a, b):
    return a-b
fun(1, 2)      # 结果为 1-2 = -1

2. 默认参数

定义函数时写入默认参数,即便不传参也不会显示错误,如下例:

def function (param = 0)
    return param

规范: 将默认的、变化不大的写在后面,变化大的参数写在前面

3. 可更改与不可更改参数

所有的变量都可以理解是内存中一个对象的“引用”,而对象有两种,“可更改”(mutable)与“不可更改”(immutable)对象。在python中,strings, tuples, 和numbers是不可更改的对象,而list,dict等则是可以修改的对象,看下例:

a = 1
def fun(a):
    a = 2
print a     # 结果为1,不会随函数调用而更改
a = []
def fun(a):
    a.append(1)
print a     # 结果为[1],随函数调用而更改

4. 可变参数

可变参数在函数调用时自动组装成tuple,直接上栗子:

定义:

def fun(*args):
    pass 

调用方法一:

fun(1,2,3)

调用方法二:

params = [1,2,3]
fun(*params)

5. 关键字参数

关键字参数在函数调用时自动组装成dict, 可不传,也可传入任意个数的关键字参数(必须传入参数名),上栗子:

定义:

def fun(**kwargs):
    return kw 

调用方法一:

fun(city = 'Beijing')  # 返回{'city':'Beijing'}

调用方法二:

fun(gender ='M', job = 'Coder')  # 返回{'gender':'M', 'job':'Coder'}

备注:当传入一个dict时,函数内部对其修改不会影响函数外的dict

6. 命名关键字参数

限制了传入的关键字参数,只接受固定名称参数传入,如下:

def fun(paraA, paraB, *, keyParaA, keyParaB):
    pass

则只有key为keyParaA和keyParaB的关键字函数可以传入。

7. *args and **kwargs

当不确定函数里将要传递多少参数时你可以用*args,相似的,**kwargs允许使用没有事先定义的参数名;
你也可以混着使用,命名参数首先获得参数值然后所有的其他参数都传递给*args**kwargs,命名参数在列表的最前端,如:

def table_things(titlestring, **kwargs)

*args**kwargs可以同时在函数的定义中,但是*args必须在**kwargs前面。

2. Python方法

Python有三种方法,分别是实例方法,静态方法(staticmethod)以及类方法(classmethod),结合下例说明一下这三种方法的区别:

def fun(x):
    print "executing fun(%s)"%(x)

class A(object):
    def fun(self,x):
        print "executing fun(%s,%s)"%(self,x)

    @classmethod
    def class_fun(cls,x):
        print "executing class_fun(%s,%s)"%(cls,x)

    @staticmethod
    def static_fun(x):
        print "executing static_fun(%s)"%x

a=A()

接下来我们来结合栗子对这三种方法做一下讲解。
对于实例方法,在类里每次定义方法的时候都需要绑定一个实例,在上栗中,fun()就是实例方法,它的调用离不开实例,所以我们把实例自己(self) 作为参数传给方法,便能进行方法与实例的绑定;
显然易见,class_fun()就是类方法了,而它则是通过cls来绑定了类;
而静态方法则不需要对谁进行绑定,那么这三种方法在调用时有什么区别呢?

三种方法调用区别.png

3. Python中的下划线

废话不说直接上栗子:

>>> class MyClass():
...     def __init__(self):
...             self.__superprivate = "Hello"
...             self._semiprivate = ", world!"
...
>>> mc = MyClass()
>>> print mc.__superprivate
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: myClass instance has no attribute '__superprivate'
>>> print mc._semiprivate
, world!
>>> print mc.__dict__
{'_MyClass__superprivate': 'Hello', '_semiprivate': ', world!'}

__foo__:只是约定,Python内部的名字,用来区别其他用户自定义的命名,以防冲突。

_foo:只是约定,用来指定变量私有.程序员用来指定私有变量的一种方式;

__foo:这个有真正的意义:解析器用_classname__foo来代替这个名字,以区别和其他类相同的命名。

4. Python装饰器

1. 两点定义:

2、 栗子

def log (func):
    @functools.wraps (func)       
    def wrapper (*args, **kw):
        print ( ‘call %s’ %func.name)
        return func (*args, **kw)
    return wrapper
       
@log
def now ( ):
    print (‘2017-05-09’)

3. 说明

在上栗中,调用now()时,now()方法会作为参数传入log()方法,实际上是调用了以now()为参数的log()方法;
上栗的打印内容是:

call now ( ):
2017-05-09

这么解释或许更加专业,原来的now()函数仍然存在,只是现在同名的now变量指向了新的函数log(now),返回wrapper()函数。

5. Lambda

Lambda又称匿名函数,当我们需要使用一个简单的且无需重复调用的函数时,就可以使用lambda,优雅又简洁。其使用方法如下例:

lambda 参数 : 返回值

是不是超简单,那看一下具体使用吧:

map( lambda x: x*x, [y for y in range(10)] )

上述代码等价于:

def sq(x):
    return x * x

map(sq, [y for y in range(10)])

使用lambda可以有效减少代码量,这样的写法是将「遍历列表,给遇到的每个元素都做某种运算」的过程从一个循环里抽象出来成为一个函数 map,然后用 lambda 表达式将这种运算作为参数传给 map。Python 之中,类似能用到 lambda 表达式的「高级」函数还有sort,reduce,filter等等。

6. map(),reduce(),filter()

既然说到了lambda,那就不得不提map()、reduce()和filter(),下面就一一介绍一下吧:

1. map()

map()函数接收两个参数,一个是函数,一个是序列,map将传入的函数依次作用到序列的每个元素,并把结果作为新的list返回。
比如我们有一个函数f(x)=x*x,要把这个函数作用在一个list [1, 2, 3, 4, 5, 6, 7, 8, 9]上,就可以用map()实现如下:

map(f, [1, 2, 3, 4, 5, 6, 7, 8, 9])

map()传入的第一个参数是f,即需要对列表中的元素进行的操作,第二个参数是迭代列表,返回则是一个新的经过处理后的列表。
map()作为高阶函数,将运算规则抽象了,将列表中的数字转为字符串只需要一行代码:

map(str, [1, 2, 3, 4, 5, 6, 7, 8, 9])

2. reduce()

与map()相同,reduce()同样接收两个参数,第一个是函数(这个函数必须接收两个参数),第二个是迭代列表,它的效果如下:

reduce(f, [x1, x2, x3, x4]) = f(f(f(x1, x2), x3), x4)

即列表中的第一个元素与第二个元素作为参数传入f()的返回值,与列表中的第三个元素再次作为参数传入f()......

3. filter()

filter()函数用于过滤序列。
又和map()类似的是,filter()也接收一个函数和一个序列。和map()不同的时,filter()把传入的函数依次作用于每个元素,然后根据返回值是True还是False决定保留还是丢弃该元素,上栗子:

def is_odd(n):
    return n % 2 == 1

filter(is_odd, [1, 2, 4, 5, 6, 9, 10, 15])

# 结果: [1, 5, 9, 15]

7. Python中的拷贝

上个栗子一目了然:

import copy
a = [1, 2, 3, 4, ['a', 'b']]  #原始对象

b = a  #赋值,传对象的引用
c = copy.copy(a)  #对象拷贝,浅拷贝
d = copy.deepcopy(a)  #对象拷贝,深拷贝

a.append(5)  #修改对象a
a[4].append('c')  #修改对象a中的['a', 'b']数组对象

print 'a = ', a
print 'b = ', b
print 'c = ', c
print 'd = ', d

输出结果:
a =  [1, 2, 3, 4, ['a', 'b', 'c'], 5]
b =  [1, 2, 3, 4, ['a', 'b', 'c'], 5]
c =  [1, 2, 3, 4, ['a', 'b', 'c']]
d =  [1, 2, 3, 4, ['a', 'b']]

8. Python中的正则表达式

1.预设元字符

2.基本元字符

3.重复匹配

4.贪婪与非贪婪

5.正则引擎

写了那么多,但每次写正则的时候,我还是会用度娘 =.=

上一篇 下一篇

猜你喜欢

热点阅读