Hello World

C++ include VS Python import

Difference

C++ include

#include is “copy-paste this file”. For example, you can #include a file into itself, and get this ridiculousness.You can also have a snippet of code in a file and #include it everywhere you want.
#include in C and C++ is a textual include.

Python import

import in Python is very different – no textual inclusion at all!

Rather, Python’s import lets you access names exported by a self-contained, separately implemented module. Some #includes in C or C++ may serve similar roles – provide access to publicly accessible names from elsewhere – but they could also be doing so many other very different things, you can’t easily tell.

More about Python’s import

在Python中,并不是任何代码块都能引入新的作用域,这与C有很大的不同:

1
2
3
4
5
6
7
8
#include<stdio.h>
int main() {
if(2 > 0) {
int i = 0;
}
printf("i = %d", i);
return 0;
}

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

但是,在Python中却并非如此:

1
2
3
4
if True:
i = 0

print i

在这段代码中,if子句并没有引入一个局部作用域,变量i仍然处在全局作用域中,因此,变量i对于接下来的print语句是可见的。
实际上,在Python中,只有模块,类以及函数才会引入新的作用域,其它的代码块是不会引入新的作用域的。

在Python中,使用一个变量之前不必预先声明它,但是在真正使用它之前,它必须已经绑定到某个对象, 而名字绑定将在当前作用域中引入新的变量,同时屏蔽外层作用域中的同名变量,不论这个名字绑定发生在当前作用域中的哪个位置。

1
2
3
4
def f():
print i

f()

运行结果将显示:NameError: global name 'i' is not defined Python首先在函数f的本地作用域中查找变量i,查找失败,接着在全局作用域和内置作用域中查找变量i,仍然失败,最终抛出NameError异常。

1
2
3
4
5
6
7
8
i = 0

def f():
i = 8
print i

f()
print i

运行结果显示:8和0。i = 8是一个名字绑定操作,它在函数f的局部作用域中引入了新的变量i,屏蔽了全局变量i,因此f内部的print语句看到的是局部变量i,f外部的print语句看到的是全局变量i

1
2
3
4
5
6
i = 0
def f():
print i
i = 0

f()

运行结果显示:UnboundLocalError: local variable 'i' referenced before assignment在这个例子当中,函数f中的变量i是局部变量,但是在print语句使用它的时候,它还未被绑定到任何对象之上
(名字绑定将在当前作用域中引入新的变量,同时屏蔽外层作用域中的同名变量,不论这个名字绑定发生在当前作用域中的哪个位置),所以抛出异常。

在Python中,名字绑定在所属作用域中引入新的变量,同时绑定到一个对象。名字绑定发生在以下几种情况之下:

  1. 参数声明:参数声明在函数的局部作用域中引入新的变量;
  2. 赋值操作:对一个变量进行初次赋值会在当前作用域中引入新的变量,后续赋值操作则会重新绑定该变量;
  3. 类和函数定义:类和函数定义将类名和函数名作为变量引入当前作用域,类体和函数体将形成另外一个作用域;
  4. import语句:import语句在当前作用域中引入新的变量,一般是在全局作用域
  5. for语句:for语句在当前作用域中引入新的变量(循环变量);
  6. except语句:except语句在当前作用域中引入新的变量(异常对象)。

在Python中,类定义所引入的作用域对于成员函数是不可见的,这与C++或者Java是很不同的,因此在Python中,成员函数想要引用类体定义的变量,必须通过self或者类名来引用它。