python作用域

  • python无块级作用域 看c语言代码:
#include<stdio.h>
int main() {
if( > ) {
int i = ;
}
printf("i = %d", i);
return ;
}

在这段代码中,if子句引入了一个局部作用域,变量i就存在于这个局部作用域中,但对外不可见,因此,接下来在printf函数中对变量i的引用会引发编译错误,但是在python中并非如此
看下面代码:

if 1 == 1:
name = 'fuzj'
print(name)

在这段代码中,if子句并没有引入一个局部作用域,变量i仍然处在全局作用域中,因此,变量i对于接下来的print语句是可见的
所以,python无块级作用域。

  • python作用域是函数、类、模块

代码:

def f1():
name = 'fuzj' print(name) #打印报错

函数f1已经将name的变量作用域隔离,所以在函数外print的时候会提示找不到name变量

  • python的作用域链查找顺序是由内向外找 python在作用域中查找是由内向外找,即先找函数里面的局部变量,然后在找全局变量,直到找不到报错,看下面例子,
name = 'fuzj'

def f1():
name = 'jie'
print(name) f1()
输出结果是jie
  • python的作用域在执行之前已经确定 python 解释器解释完代码之后,代码中的作用域已经确定,当此函数被调用时,会优先查找自己作用域,然后再查找全局
name = 'fuzj'

def f1():
print(name) def f2():
name = 'jie'
f1() f2() 输出结果:fuzj
name = 'fuzj' def f1():
print(name) def f2():
name = 'jie'
return f1 res = f2()
res() 输出结果为fuzj

通过上面的例子说明,f1在python解释器解释完之后,其作用域已经确认,作用域链也确认,同样f2函数也已经确认,所以后面执行的时候,哪个函数被调用就执行那个函数,从而查找之前已经定义好的作用域

吊炸天的案例

  • 铺垫
>>> li = [x+1 for x in range(10)]    #特殊语法,for后面循环生成了列表的元素,最终组成了一个列表,此时for循环10以内的数,并让每个x加1,最后组成li的列表
>>> print(li)
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> li = [x+1 for x in range(10) if x>7] #增加判断条件,x大于7的才加1
>>> print(li)
[9, 10]

理解了上面的铺垫,请看下面案例

  • 案例
>>> li = [lambda :x for x in range(10)]
>>> print(li)
[<function <listcomp>.<lambda> at 0x101bdbae8>, <function <listcomp>.<lambda> at 0x101bdbb70>, <function <listcomp>.<lambda> at 0x101bdbbf8>, <function <listcomp>.<lambda> at 0x101bdbc80>, <function <listcomp>.<lambda> at 0x101bdbd08>, <function <listcomp>.<lambda> at 0x101bdbd90>, <function <listcomp>.<lambda> at 0x101bdbe18>, <function <listcomp>.<lambda> at 0x101bdbea0>, <function <listcomp>.<lambda> at 0x101bdbf28>, <function <listcomp>.<lambda> at 0x101bec048>]
>>> print(li[0])
<function <listcomp>.<lambda> at 0x101bdbae8>
>>> print(li[0]())
9
>>> print(li[1]())
9

是否已经懵B?
看下面解释:

  • 1.首先li是个列表
  • 2.lambda 表达式其实就是一个简单的函数,分号前是参数,分号后是return的表达式,此案例中,lambda返回了x的值
  • 3.根据上面的基础,li列表中的元素一个个的lambda表达式,即li = [lambda :x,lambda :x....]
  • 4.函数在没有执行前,函数内部代码是不执行的,所以,打印li,输出的是lambda表达式对象
  • 5.函数加括号表示执行函数
  • 6.li中第一个元素是函数,所以li0表示执行第一个函数,此时才真正开始执行函数,而lambda表达式中没有定义x的参数,所以取for循环的结果,最终拿到9

python多继承

python2.7和python3中类有差别,python2.7中将类分给经典类和新式类,python3中全部是新式类,他们在多继承时,类的不同,继承顺序不一样

  • python3类的多继承

详情请猛击这里:http://www.cnblogs.com/pycode/p/class.html

  • python2.7多继承

    •   经典类:

      无继承其他类便是经典类

class Foo:
pass
    •     新式类

    有继承其他父类,或者object类,此类便是新式类

class Foo(object):
pass


    •     继承规则

      Python的类如果继承了多个类,那么其寻找方法的方式有两种,分别是:深度优先和广度优先

当类是经典类时,多继承情况下,会按照深度优先方式查找
当类是新式类时,多继承情况下,会按照广度优先方式查找

案例

    •   经典类多继承
class D:

    def f1(self):
print("D.f1") class B(D): def f(self):
print("B.f1") class C(D): def f1(self):
print("C.f1") class A(B, C): def f(self):
print("A.f") a = A()
a.f1()
输出结果:
D.f1 由于class D 是一个经典类,其中B和C都继承D,A继承C和B,ABC是新式类,,所以会根据深度优先的继承规则,所以输出的结果为class D的f1
    • 新式类多继承
class D(object):

    def f1(self):
print("D.f1") class B(D): def f(self):
print("B.f1") class C(D): def f1(self):
print("C.f1") class A(B, C): def f(self):
print("A.f") a = A()
a.f1()
输出结果:
C.f1 由于class D继承了object,所以ABCD都是新式类。按找广度优先的原则最后输出的是C.f1

python作用域和多继承的更多相关文章

  1. Python作用域详述

    作用域是指变量的生效范围,例如本地变量.全局变量描述的就是不同的生效范围. python的变量作用域的规则非常简单,可以说是所有语言中最直观.最容易理解的作用域. 在开始介绍作用域之前,先抛一个问题: ...

  2. Python3基础-Python作用域详述(转载)

    转载文章 转载文章 作者:骏马金龙 出处:http://www.cnblogs.com/f-ck-need-u/p/9925021.html Python作用域详述 作用域是指变量的生效范围,例如本地 ...

  3. Python中的单继承与多继承实例分析

    Python中的单继承与多继承实例分析 本文实例讲述了Python中的单继承与多继承.分享给大家供大家参考,具体如下: 单继承 一.介绍 Python 同样支持类的继承,如果一种语言不支持继承,类就没 ...

  4. 深入super,看Python如何解决钻石继承难题 【转】

    原文地址 http://www.cnblogs.com/testview/p/4651198.html 1.   Python的继承以及调用父类成员 python子类调用父类成员有2种方法,分别是普通 ...

  5. python中使用多继承

    python中使用多继承,会涉及到查找顺序(MRO).重复调用(钻石继承,也叫菱形继承问题)等 MRO MRO即method resolution order,用于判断子类调用的属性来自于哪个父类.在 ...

  6. 深入super,看Python如何解决钻石继承难题

    1.   Python的继承以及调用父类成员 python子类调用父类成员有2种方法,分别是普通方法和super方法 假设Base是基类 class Base(object): def __init_ ...

  7. python 作用域(LEGB)

    def fa(a): b = 200 c = 888 def fb(b): print(b) print(a) print(c) print(sum) return fb c = 2 sum = 10 ...

  8. Python中类的__init__继承

    Python中类的__init__继承 概念: 定义父类 In [10]: class Person: ....: def __init__(self,name,age,sex): ....: sel ...

  9. Python设计模式 - 基础 - 封装 & 继承 & 多态

    面向对象的核心是对象,世间万物都可以看作对象,任何一个对象都可以通过一系列属性和行为来描述,可以包含任意数量和类型的数据或操作.类是用来描述具有相同属性和方法的所有对象的集合.类通常是抽象化的概念,而 ...

随机推荐

  1. C++的单例模式与线程安全单例模式(懒汉/饿汉)

    1 教科书里的单例模式 我们都很清楚一个简单的单例模式该怎样去实现:构造函数声明为private或protect防止被外部函数实例化,内部保存一个private static的类指针保存唯一的实例,实 ...

  2. SqlServer主键和外键

    *主键 主键就是数据行的唯一标识.不会重复的列才能当主键.一个表可以没有主键,但是会非常难以处理,因此没有特殊理由表都要设定主键. *主键特点:1不能重复的列.2主键不能为null. *同名时如何处理 ...

  3. SSDB安装配置记录

    SSDB的性能很突出,与Redis基本相当了,Redis是内存型,容量问题是弱项,并且内存成本太高,SSDB针对这个弱点,使用硬盘存储,使用Google高性能的存储引擎LevelDB,适合大数据量处理 ...

  4. MySQL InnoDB表--BTree基本数据结构

    MySQL InnoDB表是索引组织表这一点应该是每一个学习MySQL的人都会首先学到的知识,这代表这表中的数据是按照主键顺序存储,也就是说BTree的叶子节点存储了所有该行的数据. 我最开始是搞Or ...

  5. 交互式makefile

    之前一直不知道在shell中调用read赋值后,怎么传给makefile中的变量,后来才恍然大悟. myname := $(shell read -p "Enter your name:&q ...

  6. sqlserver如何创建镜像图文教程(转)

    由于工作中需要做SQL的镜像异地备份,以前都没有研究过,百度了一个文章记录下,方便以后查询 转载地址:http://jingyan.baidu.com/article/d5c4b52b20843fda ...

  7. ffmpeg编译常规大全

    其中有需要CMake的,可以直接sudo apt-get install cmake   编译yasm wget http://www.tortall.net/projects/yasm/releas ...

  8. 国内经典BI系统架构分析

    谈起商业智能BI,也许大家并不陌生,但你是否了解国内的各类BI系统架构? 自国内商业智能发展以来,就系统结构方面已经历了多次优化性的变革.目前国内商业智能BI系统的经典架构的模式包括数据层.业务层和应 ...

  9. android:exported 属性详解

    属性详解 标签: android 2015-06-11 17:47 27940人阅读 评论(7) 收藏 举报 分类: Android(95) 项目点滴(25) 昨天在用360扫描应用漏洞时,扫描结果, ...

  10. 深入理解Java之泛型

    原文出处: absfree 1. Why ——引入泛型机制的原因 假如我们想要实现一个String数组,并且要求它可以动态改变大小,这时我们都会想到用ArrayList来聚合String对象.然而,过 ...