python——抽象

抽象是程序能够被人们理解的关键所在。
你不需要知道具体的操作细节,只需要这是知道是做什么的。

一、自定义函数

一般而言,要判断某个对象是否可调用,可使用内置函数callable。

a = 1
y = math.sqrt
print(callable(a))  # False
print(callable(y))  # True
# 定义一个函数
def welcome(name):
    string = 'Hello ' + name + '!'
    return string

# 调用这个函数
print(welcome('leo-zu'))
a = welcome
print(callable(a))  # 查看对象是否能被调用

1.1给函数编写文档
给函数编写文档,可添加注释。另一种编写注释的方式,就是添加独立的字符串。
放在函数开头的字符串成为文档字符串,将作为函数的一部分存储起来。

def welcome(name):
    """say hello word."""
    string = 'Hello ' + name + '!'
    return string

# __doc__是函数的一个属性
print(welcome.__doc__)
# say hello word.

特殊的内置函数help很有用,可使用它获取有关函数的信息,其中包含函数的文档字符串

help(welcome)
# welcome(name)
#     say hello word.

1.2注意
有些函数是没有返回值的。不包含return或者包含return,但是没有在return后面指定值。

警告:如果你在if之类的语句中返回值,务必确保其他分支也返回值,以免在调用者期望函数返回一个序列时,不小心返回了None。

二、参数魔法
参数的值分为形参和实参。形参就是定义函数时。函数名后面的变量。实参就是调用函数时提供的值。此处的值为实参。
我们需要确保提供的参数正确时完成任务,并在参数不对时以显而易见的方式失败。(通常使用断言或异常)

2.1

字符串(以及数和元组)时不可变的,列表是可变的。

# 元组不可变
a = (1, 2)
c = a
c[0] = 3
print(a)
# TypeError: 'tuple' object does not support item assignment

# 列表可变,因为b和d都指向同一个列表,所以修改d,b也会随之改变。但是如果使用copy就不会改变了
b = [1, 2]
d = b
d[0] = 3
print(b)
# [3, 2]

2.2关键字参数和默认值

def hello_1(greeting, name):
    print('{},{}!'.format(greeting, name))
    
    
def hello_2(name, greeting):
    print('{},{}!'.format(name, greeting))
 
# 上面两个函数的功能一样,只是参数的位置变了

有时候,参数的排列顺序可能难以记住,尤其是参数很多时。为了简化调用工作,可指定参数名称。

# 关键字参数
# 这样使用名称指定参数被称为关键字参数
# 主要优点是有助于澄清各个参数的作用。
hello_1(greeting='Hello', name='world')
hello_1(name='world!', greeting='Hello')
hello_2(name='Hello', greeting='world')
# Hello,world!
# Hello,world!
# world!,Hello!

关键字参数最大的优点在于,可以指定默认值。

# 指定默认值
def hello_3(greeting='Hello', name='world'):
    print('{},{}!'.format(greeting, name))


hello_3()
hello_3(greeting='Hi')
# Hello,world!
# Hi,world!

通常不应结合使用位置参数和关键字参数,除非你知道这样做的后果。一般而言,除非必不可少的参数很少,而带默认值的可选参数很多,否则不应结合使用关键字参数和位置参数。

2.3收集参数

有时候,允许用户提供任意数量的参数很有用。例如每次只能存储一个姓名,但是如果能够同时存储任意数量的姓名,该怎么办呢?

# 收集参数
def print_params(*params):
    print(params)


print_params('h', 'e', 'l', 'l', 'o')
# 可以看到有*的参数将被放在元组中。
# ('h', 'e', 'l', 'l', 'o')


def print_params_2(title, *params):
    print(title)
    print(params)


print_params_2('Hello:', 'h', 'e', 'l', 'l', 'o')
# *将会收集余下的位置参数。如果没有可供收集的参数,params将会是一个空元组
# Hello:
# ('h', 'e', 'l', 'l', 'o')

*也可以放在其他位置,它不会收集关键字参数。要收集关键字参数,需要‘“**”

def print_params_3(**params):
    print(params)


print_params_3(x=1, y=2, z=3)
# 这样得到的是一个字典,而不是元组。
# {'x': 1, 'y': 2, 'z': 3}

# 将上面这些技术结合起来
def print_params_4(x, y, z=3, *pospar, **keypar):
    print(x, y, z)
    print(pospar)
    print(keypar)


print_params_4(1, 2, 3, 5, 6, 7, foo=1, bar=2)
# 1 2 3
# (5, 6, 7)
# {'foo': 1, 'bar': 2}

2.4分配参数
分配参数与收集参数相反。

def add(x, y):
    return x + y


params = (1, 2)
# 对于元组,使用*来实现分配参数
total = add(*params)
print(total)


# 也可以用于参数列表的一部分,条件是这部分位于参数列表的末尾。
# 通过使用运算符**,可将字典中的值分配给关键字参数。
def hello_3(greeting='Hello', name='world'):
    print('{},{}!'.format(greeting, name))


params = {'name': 'leo', 'greeting': 'Hello'}
hello_3(**params)
# 3
# Hello,leo!

三、作用域

变量到底是什么?可将其看作指向值的名称。

有一个内置函数vars,它返回作用域

x = 1
scope = vars()
print(scope['x'])
# 1
scope['x'] += 1
print(x)
# 2

这种“看不见的字典”称为命名空间和作用域。
有多少个命名空间呢?除全局作用域外,每个函数调用都将创建一个。

慎用全局变量。不当使用可能会导致bug。
如果非要使用全局变量,可以使用globals函数来访问全局变量,返回一个包含全局变量的字典。
locals函数返回一个包含局部变量的字典。

作用域嵌套:可以将一个函数放在另一个函数内。

# 嵌套
# multiplier返回一个函数,而不是调用它
# 每当外部函数被调用时,都将重新定义内部函数。
# 而变量factory的值也可能不同。
def multiplier(factor):
    # 可在内部函数中访问来自外部局部作用域的变量。
    # 像multiplyByFactor这样存储其所在作用域的函数称为闭包
    def multiplyByFactor(number):
        return number * factor
    return multiplyByFactor


double = multiplier(2)
a = double(5)
print(a)
# 10

四、函数式编程

你可能习惯了像使用其他对象(字符串、数、序列等)一样使用函数:
将其赋值给变量,将其作为参数进行传递,以及从函数返回它们。

python提供了一些有助于进行这种函数式编程的函数:map、filter、reduce。
其中在新版本的python中,函数map和filter用途不打,应该使用列表推导来代替它们。

# 两者等价
b = list(map(str, range(10)))
a = [str(i) for i in range(10)]
print(b)
print(a)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值