一、抽象
1.抽象:
抽象就是隐藏细节的艺术。比如通过定义处理细节的函数,可以使得程序更抽象。(说白了就是黑盒子,类似于C++中的类的封装,也就是接口函数)
2.自定义函数:使用def语句定义,接受参数输入,并可以返回一个或者多个值。示例如下:
def function(parm1,parm2,...):
......
return res1,res2,...
介绍一个内置函数callable(fun),作用:判断某个对象是否可以调用。
3.参数:给参数赋值的方式有如下几种:
- 按照位置顺序赋值
- 关键字参数赋值,示例如下:此时参数顺序就无关紧要了
>>>def say(greeting, name): .....print('{},{}!'.format(greeting,name)) >>>say(greeting = 'hello', name = 'Jerry') hello,Jerry!
-
指定默认值
>>>def say(greeting = 'hello', name): ....print('{},{}!'.format(greeting,name))
两点注意:
(1) “n is name”和“n == name” 不一样,n is name如果返回true,说明两个变量指向同一个值,而后者若返回true只能说明两个变量所指向的值是相等的。
(2)同一个列表赋给两个变量的时候,两个变量将同时指向这个列表。
4.遮盖问题:如果在函数内的参数的名字和一个全局变量相同,那么就无法直接访问全局变量,因为它被局部变量遮
住了。如果需要,可使用函数 globals 来访问全局变量,示例如下:
>>>x = 1
>>>def change_global():
global x
x = x + 1
>>>change_global()
>>>x
2
5.作用域嵌套:Python函数可以嵌套,即可将一个函数放在另一个函数内,例如
def foo():
def bar():
print("Hello, world!")
bar()
6.递归:所谓递归就是调用自身。递归函数通常包含下面两部分。
- 基线条件:满足这种条件时函数将直接返回一个值。(针对最小的问题)
- 递归条件:包含一个或多个调用,这些调用旨在解决问题的一部分
经典案例:阶乘和幂的实现
一、阶乘,即求n!
def factorial(n):
if x == 1:
return 1
else:
return n * factorial(n-1)
二、幂:pow(x,n)即求x的n次方
def pow(x,n):
if n == 0:
return 1
else:
return x * pow(x,n-1)
那么使用递归意义何在呢?不可以直接使用循环吗?答案是肯定可以的,而且在大多数情况下,使用循环的效率可能更高。然而,在很多情况下,使用递归的可读性更高,且有时要高得多,在你理解了函数的递归式定义时尤其如此。
7.介绍的新函数
(1)map(func, seq[, seq, ...]) :对序列中的所有元素执行函数
(2)filter(func, seq) :返回一个列表,其中包含对其执行函数时结果为真的所有元素
(3)reduce(func, seq[, initial]) :等价于 func(func(func(seq[0], seq[1]), seq[2]), ...)
(4)apply(func[, args[, kwargs]]): 调用函数(还提供要传递给函数的参数)
二、再谈抽象
1.对象
对象是由一系列数据(属性)以及一套访问和操作这些数据的方法所组成。属性:属于对象的变量。方法:存储在属性中的函数。对象的方法与函数的区别:对象的方法总是将其所属的对象作为第一个参数,这个参数通常被命名为 self。
2.类
每个对象都属于特定的类,并被称为该类的实例。有两个概念:子类和超类,介绍如下
子类:一个类的对象为另一个类的对象的子集时,前者就是后者的子类。
超类:而后者就是前者的超类。
那么如何创建自定义类呢:
class Person:
def set_name(self, name):
self.name = name
def get_name(self):
return self.name
def greet(self):
print("Hello, world! I'm {}.".format(self.name))
3.抽象基类
抽象类是不能(至少是不应该)实例化的类,其功能是定义子类需要实现的一组通用的抽象方法。示例如下:
from abc import ABC, abstractmethod
class Talker(ABC):
@abstractmethod
def talk(self):
pass
形如@this的东西被称为装饰器 ,@abstractmethod 用来将方法标记为抽象的——在子类中必须实现的方法。
4.多态
多态指的是能够同样地对待不同类型和类的对象,即无需知道对象属于哪个类就可调用其方法。
5.封装
对象可能隐藏(封装)其内部状态。在有些语言中,这意味着对象的状态(属性)只能通过其方法来访问。在Python中,所有的属性都是公有的,但直接访问对象的状态时程序员应谨慎行事,因为这可能在不经意间导致状态不一致。
6.继承
一个类可以是一个或多个类的子类,在这种情况下,子类将继承超类的所有方法。你可指定多个超类,通过这样做可组合正交(独立且不相关)的功能。为此,一种常见的做法是使用一个核心超类以及一个或多个混合超类。