Python 进阶

*args 和 **kwargs

  • 接收不定长参数
  • 接受不定长键值对
def test_var_args(f_arg, *argv):
    print("first normal arg:", f_arg)
    for arg in argv:
        print("another arg through *argv:", arg)

test_var_args('yasoob', 'python', 'eggs', 'test')
first normal arg: yasoob
another arg through *argv: python
another arg through *argv: eggs
another arg through *argv: test
def greet_me(**kwargs):
    for key, value in kwargs.items():
        print("{0} == {1}".format(key, value))
greet_me(**{"arg3": 3, "arg2": "two", "arg1": 5})
arg3 == 3
arg2 == two
arg1 == 5

迭代器生成斐波拉切数列

# generator version
def fibon(n):
    a = b = 1
    for i in range(n):
        yield a
        a, b = b, a + b
for i in fibon(10):
    print(i)
1
1
2
3
5
8
13
21
34
55
# next method
gen = fibon(10)
print(next(gen))
print(next(gen))
print(next(gen))
print(next(gen))
print(next(gen))
1
1
2
3
5

Map,Filter 和 Reduce

Map

将一个函数映射到一个输入列表的所有元素上

# 每个元素使用函数 
list(map(lambda x: x**2, range(5)))
[0, 1, 4, 9, 16]
# 多函数操作
def multiply(x):
        return (x*x)
def add(x):
        return (x+x)

funcs = [multiply, add]
for i in range(5):
    value = list(map(lambda x: x(i), funcs))
    print(value)
[0, 0]
[1, 2]
[4, 4]
[9, 6]
[16, 8]

filter

过滤列表中的元素,并且返回一个由所有符合要求的元素所构成的列表,符合要求时返回值为True

# 过滤大于等于0的元素
number_list = range(-5, 5)
less_than_zero = filter(lambda x: x < 0, number_list)
print(list(less_than_zero))
[-5, -4, -3, -2, -1]

reduce 用于对列表整体的运算

用传给 reduce 中的函数 function(有两个参数)先对集合中的第 1、2 个元素进行操作,得到的结果再与第三个数据用 function 函数运算,最后得到一个结果。

# 输出列表的累乘
from functools import reduce
reduce( (lambda x, y: x * y), [1, 2, 3, 4, 5] )
120

检测重复元素

some_list = ['a', 'b', 'c', 'b', 'd', 'm', 'n', 'n']
set([x for x in some_list if some_list.count(x) > 1])
{'b', 'n'}

三元运算符

(1, 2)[False]
1
2 if False else 1
1

装饰器

自定义装饰器

装饰器封装一个函数,并且用这样或者那样的方式来修改它的行为

def a_new_decorator(a_func):
    '''自定义装饰器'''
    def wrapTheFunction():
        print("I am doing some boring work before executing a_func()")

        a_func() # 被装饰的函数

        print("I am doing some boring work after executing a_func()")

    return wrapTheFunction

def a_function_requiring_decoration():
    '''被装饰的函数'''
    print("I am the function which needs some decoration to remove my foul smell")

print("before decorate:")
a_function_requiring_decoration()
a_function_requiring_decoration = a_new_decorator(a_function_requiring_decoration)
print("\nafter decorate:")
a_function_requiring_decoration()
before decorate:
I am the function which needs some decoration to remove my foul smell

after decorate:
I am doing some boring work before executing a_func()
I am the function which needs some decoration to remove my foul smell
I am doing some boring work after executing a_func()
'''使用@形式'''
def a_new_decorator(a_func):

    def wrapTheFunction():
        print("I am doing some boring work before executing a_func()")

        a_func()

        print("I am doing some boring work after executing a_func()")

    return wrapTheFunction

@a_new_decorator
def a_function_requiring_decoration():
    print("I am the function which needs some decoration to "
          "remove my foul smell")
a_function_requiring_decoration()
I am doing some boring work before executing a_func()
I am the function which needs some decoration to remove my foul smell
I am doing some boring work after executing a_func()

解决上面代码的函数名称改变的问题

print(a_function_requiring_decoration.__name__)
# 函数名称应该是 a_function_requiring_decoration
wrapTheFunction
'''使用@wraps解决'''
from functools import wraps

def a_new_decorator(a_func):
    @wraps(a_func)
    def wrapTheFunction():
        print("I am doing some boring work before executing a_func()")
        a_func()
        print("I am doing some boring work after executing a_func()")
    return wrapTheFunction

@a_new_decorator
def a_function_requiring_decoration():
    """Hey yo! Decorate me!"""
    print("I am the function which needs some decoration to "
          "remove my foul smell")

print(a_function_requiring_decoration.__name__)
# Output: a_function_requiring_decoration
a_function_requiring_decoration

装饰器应用

'''日志'''
from functools import wraps

def logit(func):
    @wraps(func)
    def with_logging(*args, **kwargs):
        print(func.__name__ + " was called")
        result = func(*args, **kwargs)
        print(func.__name__ + " was ended")
        return result
    return with_logging

@logit
def addition_func(x):
   """Do some math."""
   return x + x


print(addition_func(4))
addition_func was called
addition_func was ended
8
'''检测参数正确性'''
def params_chack(a_type, b_type):
    def _outer(func):
        @wraps(func)
        def _inner(a, b):
            assert isinstance(a, a_type) and isinstance(b, b_type) # isinstance和type类似, isinstance考虑继承
            return func(a, b)
        return _inner
    return _outer

# 使用装饰器
@params_chack(int, (list, tuple))# 第一个参数是int, 第二个是list或tuple
def foo(a, b):
    print("a=%s, b=%s" % (a, b))
    return "Right!"

# 测试用例
print(foo(1, [2, 3]))   # 参数正确
print(foo(1, (2, 3)))  # 参数正确
# print(foo(1, 2))        # 参数错误
a=1, b=[2, 3]
Done!
a=1, b=(2, 3)
Done!
'''构建装饰器类'''
class ParamCheck(object):

    def __init__(self, *types, **kwtypes):
        self.types = types
        self.kwtypes = kwtypes
        return

    def __call__(self, func):
        @wraps(func)
        def _inner(*args, **kwargs):
            result = [isinstance(_param, _type) for _param, _type in zip(args, self.types)]
            assert all(result), "params_chack: invalid parameters"
            result = [isinstance(kwargs[_param], self.kwtypes[_param]) for _param in kwargs if _param in self.kwtypes]
            assert all(result), "params_chack: invalid parameters"
            return func(*args, **kwargs)
        return _inner

# 使用装饰器
@ParamCheck(int, str, (list, tuple))
def foo(a, b, c):
    print("a=%s, b=%s, c=%s" % (a, b, c))
    return "Right!"

# 测试用例
print(foo(1, "str", [1, 2]))    # 参数正确
print(foo(1, "str", (1, 2)))    # 参数正确
# print(foo(1, 2, (1, 2)))        # 参数错误
a=1, b=str, c=[1, 2]
Right!
a=1, b=str, c=(1, 2)
Right!

python自带装饰器

'''@property 修饰,就是将方法,变成一个属性来使用。'''
class A():


    @property
    def pfunc(self):
        return self.value

    @pfunc.setter
    def pfunc(self,value):
        self.value = value

    @property
    def pfunc1(self):
        print('this is property')


A.pfunc = 9
print(A.pfunc)
A.pfunc1
9





<property at 0x16e6e2bcf98>
'''
@classmethod  修饰类的方式
- 带修饰类方法:cls做为方法的第一个参数,隐式的将类做为对象,传递给方法,调用时无须实例化。
- 普通函数方法:self做为第一个参数,隐式的将类实例传递给方法,调用方法时,类必须实例化。
'''
class A():
    def func(self,x,y):
        return x * y

    @classmethod
    def cfunc(cls,x,y):
        return x * y

# print(A.func(5,5)) # 错误
print(A().func(5,5))
print(A.cfunc(4,5))
25
20
'''
@staticmethod  修饰类的方式
- 是把函数嵌入到类中的一种方式,函数就属于类,同时表明函数不需要访问这个类
- 修饰方法,不需要实例化
'''

class A():
    def func(self,x,y):
        return sfunc(x, y) # 直接调用


    @staticmethod
    def sfunc(x,y):
        return x * y

print(A.sfunc(6,5))
30

推导式

列表推导式

[i for i in range(30) if i % 3 is 0] # 3的除数
[0, 3, 6, 9, 12, 15, 18, 21, 24, 27]

字典推导式

'''同一个字母但不同大小写的值合并起来'''
mcase = {'a': 10, 'b': 34, 'A': 7, 'Z': 3}

mcase_frequency = {
    k.lower(): mcase.get(k.lower(), 0) + mcase.get(k.upper(), 0)
    for k in mcase.keys()
}
'''快速对换一个字典的键和值'''
{v: k for k, v in mcase.items()}
{10: 'a', 34: 'b', 7: 'A', 3: 'Z'}

集合推导式

'''跟列表推导式也是类似的。 唯一的区别在于使用大括号{}'''
{x**2 for x in [1, 1, 2]}
{1, 4}

使用C拓展

C拓展

C API

相关推荐