24资源网

24资源分享网,分享资源,收集整理资源,有态度的分享资源网

Python篇| 一些Python的高级常用语法(一)

1. 内嵌函数

【例子】def outer(): print(outer函数在这被调用) def inner(): print(inner函数在这被调用) inner() # 该函数只能在outer函数内部被调用outer()# outer函数在这被调用# inner函数在这被调用

2. 闭包

是函数式编程的一个重要的语法结构,是一种特殊的内嵌函数。

如果在一个内部函数里对外层非全局作用域的变量进行引用,那么内部函数就被认为是闭包。

通过闭包可以访问外层非全局作用域的变量,这个作用域称为 闭包作用域。

【例子】def funX(x): def funY(y): return x * y return funYi = funX(8)print(type(i)) # <class function>print(i(5)) # 40

【例子】闭包的返回值通常是函数。

def make_counter(init): counter = [init] def inc(): counter[0] += 1 def dec(): counter[0] -= 1 def get(): return counter[0] def reset(): counter[0] = init return inc, dec, get, resetinc, dec, get, reset = make_counter(0)inc()inc()inc()print(get()) # 3dec()print(get()) # 2reset()print(get()) # 0

【例子】 如果要修改闭包作用域中的变量则需要 nonlocal 关键字

def outer(): num = 10 def inner(): nonlocal num # nonlocal关键字声明 num = 100 print(num) inner() print(num)outer()# 100# 1003. Lambda表达式

匿名函数的定义

第一类:用 def 关键词定义的正规函数

第二类:用 lambda 关键词定义的匿名函数

Python 使用 lambda 关键词来创建匿名函数,而非def关键词,它没有函数名,其语法结构如下:

lambda argument_list: expression

lambda – 定义匿名函数的关键词。

argument_list – 函数参数,它们可以是位置参数、默认参数、关键字参数,和正规函数里的参数类型一样。

:- 冒号,在函数参数和表达式中间要加个冒号。

expression – 只是一个表达式,输入函数参数,输出一些值。

注意:

expression 中没有 return 语句,因为 lambda 不需要它来返回,表达式本身结果就是返回值。

匿名函数拥有自己的命名空间,且不能访问自己参数列表之外或全局命名空间里的参数。

【例子】def sqr(x): return x ** 2print(sqr)# <function sqr at 0x000000BABD3A4400>y = [sqr(x) for x in range(10)]print(y)# [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]lbd_sqr = lambda x: x ** 2print(lbd_sqr)# <function <lambda> at 0x000000BABB6AC1E0>y = [lbd_sqr(x) for x in range(10)]print(y)# [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]sumary = lambda arg1, arg2: arg1 + arg2print(sumary(10, 20)) # 30func = lambda *args: sum(args)print(func(1, 2, 3, 4, 5)) # 15

匿名函数的应用

函数式编程 是指代码中每一块都是不可变的,都由纯函数的形式组成。这里的纯函数,是指函数本身相互独立、互不影响,对于相同的输入,总会有相同的输出,没有任何副作用。

【例子】非函数式编程

def f(x): for i in range(0, len(x)): x[i] += 10 return xx = [1, 2, 3]f(x)print(x)# [11, 12, 13]

【例子】函数式编程

def f(x): y = [] for item in x: y.append(item + 10) return yx = [1, 2, 3]f(x)print(x)# [1, 2, 3]

匿名函数 常常应用于函数式编程的高阶函数 (high-order function)中,主要有两种形式:

参数是函数 (filter, map)

返回值是函数 (closure)

如,在 filter和map函数中的应用:

filter(function, iterable) 过滤序列,过滤掉不符合条件的元素,返回一个迭代器对象,如果要转换为列表,可以使用 list() 来转换。

【例子】

odd = lambda x: x % 2 == 1templist = filter(odd, [1, 2, 3, 4, 5, 6, 7, 8, 9])print(list(templist)) # [1, 3, 5, 7, 9]

map(function, *iterables) 根据提供的函数对指定序列做映射。

【例子】

m1 = map(lambda x: x ** 2, [1, 2, 3, 4, 5])print(list(m1)) # [1, 4, 9, 16, 25]m2 = map(lambda x, y: x + y, [1, 3, 5, 7, 9], [2, 4, 6, 8, 10])print(list(m2)) # [3, 7, 11, 15, 19]

除了 Python 这些内置函数,我们也可以自己定义高阶函数。

【例子】

def apply_to_list(fun, some_list): return fun(some_list)lst = [1, 2, 3, 4, 5]print(apply_to_list(sum, lst))# 15print(apply_to_list(len, lst))# 5print(apply_to_list(lambda x: sum(x) / len(x), lst))# 3.04. 类与对象对象 = 属性 + 方法

对象是类的实例。换句话说,类主要定义对象的结构,然后我们以类为模板创建对象。类不但包含方法定义,而且还包含所有实例共享的数据。

封装:信息隐蔽技术

我们可以使用关键字 class 定义 Python 类,关键字后面紧跟类的名称、分号和类的实现。

【例子】

class Turtle: # Python中的类名约定以大写字母开头 “””关于类的一个简单例子””” # 属性 color = green weight = 10 legs = 4 shell = True mouth = 大嘴 # 方法 def climb(self): print(我正在很努力的向前爬…) def run(self): print(我正在飞快的向前跑…) def bite(self): print(咬死你咬死你!!) def eat(self): print(有得吃,真满足…) def sleep(self): print(困了,睡了,晚安,zzz)tt = Turtle()print(tt)# <__main__.Turtle object at 0x0000007C32D67F98>print(type(tt))# <class __main__.Turtle>print(tt.__class__)# <class __main__.Turtle>print(tt.__class__.__name__)# Turtlett.climb()# 我正在很努力的向前爬…tt.run()# 我正在飞快的向前跑…tt.bite()# 咬死你咬死你!!# Python类也是对象。它们是type的实例print(type(Turtle))# <class type>

继承:子类自动共享父类之间数据和方法的机制

【例子】

class MyList(list): passlst = MyList([1, 5, 2, 7, 8])lst.append(9)lst.sort()print(lst)# [1, 2, 5, 7, 8, 9]

多态:不同对象对同一方法响应不同的行动

【例子】

class Animal: def run(self): raise AttributeError(子类必须实现这个方法)class People(Animal): def run(self): print(人正在走)class Pig(Animal): def run(self): print(pig is walking)class Dog(Animal): def run(self): print(dog is running)def func(animal): animal.run()func(Pig())# pig is walking

self是什么?

Python 的 self 相当于 C++ 的 this 指针。

【例子】

class Test: def prt(self): print(self) print(self.__class__)t = Test()t.prt()# <__main__.Test object at 0x000000BC5A351208># <class __main__.Test>

类的方法与普通的函数只有一个特别的区别 —— 它们必须有一个额外的第一个参数名称(对应于该实例,即该对象本身),按照惯例它的名称是 self。在调用方法时,我们无需明确提供与参数 self 相对应的参数。

【例子】

class Ball: def setName(self, name): self.name = name def kick(self): print(“我叫%s,该死的,谁踢我…” % self.name)a = Ball()a.setName(“球A”)b = Ball()b.setName(“球B”)c = Ball()c.setName(“球C”)a.kick()# 我叫球A,该死的,谁踢我…b.kick()# 我叫球B,该死的,谁踢我…

Python的魔法方法

据说,Python 的对象天生拥有一些神奇的方法,它们是面向对象的 Python 的一切…

它们是可以给你的类增加魔力的特殊方法…

如果你的对象实现了这些方法中的某一个,那么这个方法就会在特殊的情况下被 Python 所调用,而这一切都是自动发生的…

类有一个名为__init__(self[, param1, param2…])的魔法方法,该方法在类实例化时会自动调用。

【例子】

class Ball: def __init__(self, name): self.name = name def kick(self): print(“我叫%s,该死的,谁踢我…” % self.name)a = Ball(“球A”)b = Ball(“球B”)c = Ball(“球C”)a.kick()# 我叫球A,该死的,谁踢我…b.kick()# 我叫球B,该死的,谁踢我…

公有和私有

在 Python 中定义私有变量只需要在变量名或函数名前加上“__”两个下划线,那么这个函数或变量就会为私有的了。

【例子】类的私有属性实例

class JustCounter: __secretCount = 0 # 私有变量 publicCount = 0 # 公开变量 def count(self): self.__secretCount += 1 self.publicCount += 1 print(self.__secretCount)counter = JustCounter()counter.count() # 1counter.count() # 2print(counter.publicCount) # 2# Python的私有为伪私有print(counter._JustCounter__secretCount) # 2 print(counter.__secretCount) # AttributeError: JustCounter object has no attribute __secretCount

【例子】类的私有方法实例

class Site: def __init__(self, name, url): self.name = name # public self.__url = url # private def who(self): print(name : , self.name) print(url : , self.__url) def __foo(self): # 私有方法 print(这是私有方法) def foo(self): # 公共方法 print(这是公共方法) self.__foo()x = Site(老马的程序人生, https://blog.csdn.net/LSGO_MYP)x.who()# name : 老马的程序人生# url : https://blog.csdn.net/LSGO_MYPx.foo()# 这是公共方法# 这是私有方法x.__foo()# AttributeError: Site object has no attribute __foo

继承

Python 同样支持类的继承,派生类的定义如下所示:

class DerivedClassName(BaseClassName):

       statement-1

              .

              .

              .

       statement-N

BaseClassName(基类名)必须与派生类定义在一个作用域内。除了类,还可以用表达式,基类定义在另一个模块中时这一点非常有用:

class DerivedClassName(modname.BaseClassName):

       statement-1

              .

              .

              .

       statement-N

【例子】如果子类中定义与父类同名的方法或属性,则会自动覆盖父类对应的方法或属性。

# 类定义class people: # 定义基本属性 name = age = 0 # 定义私有属性,私有属性在类外部无法直接进行访问 __weight = 0 # 定义构造方法 def __init__(self, n, a, w): self.name = n self.age = a self.__weight = w def speak(self): print(“%s 说: 我 %d 岁。” % (self.name, self.age))# 单继承示例class student(people): grade = def __init__(self, n, a, w, g): # 调用父类的构函 people.__init__(self, n, a, w) self.grade = g # 覆写父类的方法 def speak(self): print(“%s 说: 我 %d 岁了,我在读 %d 年级” % (self.name, self.age, self.grade))s = student(小马的程序人生, 10, 60, 3)s.speak()# 小马的程序人生 说: 我 10 岁了,我在读 3 年级

注意:如果上面的程序去掉:people.__init__(self, n, a, w),则输出:说: 我 0 岁了,我在读 3 年级,因为子类的构造方法把父类的构造方法覆盖了。

【例子】

import randomclass Fish: def __init__(self): self.x = random.randint(0, 10) self.y = random.randint(0, 10) def move(self): self.x -= 1 print(“我的位置”, self.x, self.y)class GoldFish(Fish): # 金鱼 passclass Carp(Fish): # 鲤鱼 passclass Salmon(Fish): # 三文鱼 passclass Shark(Fish): # 鲨鱼 def __init__(self): self.hungry = True def eat(self): if self.hungry: print(“吃货的梦想就是天天有得吃!”) self.hungry = False else: print(“太撑了,吃不下了!”) self.hungry = Trueg = GoldFish()g.move() # 我的位置 9 4s = Shark()s.eat() # 吃货的梦想就是天天有得吃!s.move() # AttributeError: Shark object has no attribute x

解决该问题可用以下两种方式:

调用未绑定的父类方法Fish.__init__(self)

class Shark(Fish): # 鲨鱼 def __init__(self): Fish.__init__(self) self.hungry = True def eat(self): if self.hungry: print(“吃货的梦想就是天天有得吃!”) self.hungry = False else: print(“太撑了,吃不下了!”) self.hungry = True

使用super函数super().__init__()

class Shark(Fish): # 鲨鱼 def __init__(self): super().__init__() self.hungry = True def eat(self): if self.hungry: print(“吃货的梦想就是天天有得吃!”) self.hungry = False else: print(“太撑了,吃不下了!”) self.hungry = True

Python 虽然支持多继承的形式,但我们一般不使用多继承,因为容易引起混乱。

class DerivedClassName(Base1, Base2, Base3):

       statement-1

              .

              .

              .

       statement-N

需要注意圆括号中父类的顺序,若是父类中有相同的方法名,而在子类使用时未指定,Python 从左至右搜索,即方法在子类中未找到时,从左到右查找父类中是否包含方法。

【例子】

# 类定义class People: # 定义基本属性 name = age = 0 # 定义私有属性,私有属性在类外部无法直接进行访问 __weight = 0 # 定义构造方法 def __init__(self, n, a, w): self.name = n self.age = a self.__weight = w def speak(self): print(“%s 说: 我 %d 岁。” % (self.name, self.age))# 单继承示例class Student(People): grade = def __init__(self, n, a, w, g): # 调用父类的构函 People.__init__(self, n, a, w) self.grade = g # 覆写父类的方法 def speak(self): print(“%s 说: 我 %d 岁了,我在读 %d 年级” % (self.name, self.age, self.grade))# 另一个类,多重继承之前的准备class Speaker: topic = name = def __init__(self, n, t): self.name = n self.topic = t def speak(self): print(“我叫 %s,我是一个演说家,我演讲的主题是 %s” % (self.name, self.topic))# 多重继承class Sample01(Speaker, Student): a = def __init__(self, n, a, w, g, t): Student.__init__(self, n, a, w, g) Speaker.__init__(self, n, t)# 方法名同,默认调用的是在括号中排前地父类的方法test = Sample01(“Tim”, 25, 80, 4, “Python”)test.speak() # 我叫 Tim,我是一个演说家,我演讲的主题是 Pythonclass Sample02(Student, Speaker): a = def __init__(self, n, a, w, g, t): Student.__init__(self, n, a, w, g) Speaker.__init__(self, n, t)# 方法名同,默认调用的是在括号中排前地父类的方法test = Sample02(“Tim”, 25, 80, 4, “Python”)test.speak() # Tim 说: 我 25 岁了,我在读 4 年级

迭代器

迭代是 Python 最强大的功能之一,是访问集合元素的一种方式。

迭代器是一个可以记住遍历的位置的对象。

迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。

迭代器只能往前不会后退。

字符串,列表或元组对象都可用于创建迭代器:

【例子】

string = lsgogroupfor c in string: print(c)lsgog

【例子】

links = {B: 百度, A: 阿里, T: 腾讯}for each in links: print(%s -> %s % (each, links[each]))B -> 百度A -> 阿里T -> 腾讯for each in iter(links): print(%s -> %s % (each, links[each]))

迭代器有两个基本的方法:iter() 和 next()。

iter(object) 函数用来生成迭代器。

next(iterator[, default]) 返回迭代器的下一个项目。

iterator — 可迭代对象

default — 可选,用于设置在没有下一个元素时返回该默认值,如果不设置,又没有下一个元素则会触发 StopIteration 异常。

【例子】

links = {B: 百度, A: 阿里, T: 腾讯}it = iter(links)while True: try: each = next(it) except StopIteration: break print(each)# B# A# Tit = iter(links)print(next(it)) # Bprint(next(it)) # Aprint(next(it)) # Tprint(next(it)) # StopIteration

把一个类作为一个迭代器使用需要在类中实现两个魔法方法 __iter__() 与 __next__() 。

__iter__(self)定义当迭代容器中的元素的行为,返回一个特殊的迭代器对象, 这个迭代器对象实现了 __next__() 方法并通过 StopIteration 异常标识迭代的完成。

__next__() 返回下一个迭代器对象。

StopIteration 异常用于标识迭代的完成,防止出现无限循环的情况,在 __next__() 方法中我们可以设置在完成指定循环次数后触发 StopIteration 异常来结束迭代。

【例子】

class Fibs: def __init__(self, n=10): self.a = 0 self.b = 1 self.n = n def __iter__(self): return self def __next__(self): self.a, self.b = self.b, self.a + self.b if self.a > self.n: raise StopIteration return self.afibs = Fibs(100)for each in fibs: print(each, end=)# 1 1 2 3 5 8 13 21 34 55 89

参考来源:AI训练营Python-阿里云天池 (aliyun.com)

END

分享

收藏

点赞

在看

               
发表评论