python作用域和多继承

python作用域

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

在这段代码中,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
时间: 2024-10-09 21:26:12

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

day10 Python作用域 Python2.7与Python3.x的类继承的区别及其他

一.Python作用域   1.Python中无块级作用域 if 1 == 1: name = 'test' print(name) #输出会报错,因为name的作用域仅限于if下的代码块,而不属于全局   2.Python中以函数为作用域 def func(): func_name = 'func_test' print(func_name) #这里同样会报错,因为变量func_name的作用于func函数中   3.Python作用域链,层层嵌套,使用时从内向外找   4.Python的作用

Python Special Syntax 7:继承

继续在上一节的类的基础上测试继承: #-*-coding:utf-8 import Syntax2 class Student(Syntax2.Person): def __init__(self,name,age): Syntax2.Person.__init__(self,name) Syntax2.Person.printName(self) print('age %s' % age) self.age=age def detail(self): print('Name %s, age:%

python学习之类的继承

面向对象中一个重要的特性就是继承,继承的好处就是提高代码的重用率,减少不必要的代码.继承是父类与子类的关系,当子类继承了父类后,就具有了父类的所有变量和方法.在python中定义继承的语法是:class 派生类名(基类名).在使用python的继承时需要注意一下几点: (1)当父类定义了__init__()初始化方法时,子类不会自动调用,而需要我们显示调用,如果我们要扩展父类的变量,可以在__init__()添加参数. (2)在调用基类的方法时,需要加上基类的类名前缀,且需要带上self参数变量

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

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

(转载)深入super,看Python如何解决钻石继承难题

1.   Python的继承以及调用父类成员 python子类调用父类成员有2种方法,分别是普通方法和super方法 假设Base是基类 class Base(object): def __init__(self): print "Base init" 则普通方法如下 class Leaf(Base): def __init__(self): Base.__init__(self) print "Leaf init" super方法如下 class Leaf(Bas

Python之路Python作用域、匿名函数、函数式编程、map函数、filter函数、reduce函数

Python之路Python作用域.匿名函数.函数式编程.map函数.filter函数.reduce函数 一.作用域 return 可以返回任意值例子 def test1(): print("test1") def test(): print("test") return test1 res = test() print(res) 输出结果 test <function test1 at 0x021F5C90> 分析:这里print(res)输出的是te

python中类的多继承的搜索算法

1.Python的类可以继承多个类,Java和C#中则只能继承一个类 2.Python的类如果继承了多个类,那么其寻找方法的方式有两种,分别是:深度优先和广度优先 当类是经典类时,多继承情况下,会按照深度优先方式查找 当类是新式类时,多继承情况下,会按照广度优先方式查找 经典类和新式类,从字面上可以看出一个老一个新,新的必然包含了跟多的功能,也是之后推荐的写法,从写法上区分的话,如果 当前类或者父类继承了object类,那么该类便是新式类,否则便是经典类.   class D: def bar(

python 作用域

在写作用域前,先来了解下局部变量和全局变量.理解局部变量和全局变量后,作用域的概念就很好理解了. 局部变量:局部变量只能在局部访问到,当超过其作用域时,变失去作用. 全局变量:无论在任何作用域都可以使用.当前作用域有相同变量名的局部变量时,局部变量生效. (忘记准确定义了,忘掉他吧) 1.Python中无块集作用域 Java/C#有块集作用域 Python/JavaScript无块集作用域 所谓块集作用域,需要先了解Python的代码块概念.Python遵从严格的缩进标准,可以认为处在同一缩进之

python作用域和JavaScript作用域

JavaScript 一.JavaScript中无块级作用域 一个大括号一个作用域,就属于块级作用域,在Java和c#才存在块级作用域 function Main(){ if(1==1){ var name = 'seven'; } console.log(name); } // 输出: seven 二.JavaScript采用函数作用域 在JavaScript中每个函数作为一个作用域,在外部无法访问内部作用域中的变量 function Main(){ var innerValue = 'sev