一:可调用对象

可调用对象,是任何能通过函数操作符“()”来调用的对象。Python 有4 种可调用对象:函数,方法,类,以及一些类的实例。

1:函数

python 有 3 种不同类型的函数对象。

a:内建函数(BIFs),是用c/c++写的,编译过后放入python 解释器,然后把它们作为内建名字空间的一部分加载进系统。这些函数在_bulitin_模块中。

内建函数属性如下表:

bif.__doc__

文档字符串(或None)

bif.__name__

字符串类型的文档名字

bif.__self__

设置为None(保留给built-in 方法)

bif.__module__

存放bif 定义的模块名字(或None)

可以用dir()列出函数的所有属性:

>>> dir(type)
['__call__', '__class__', '__cmp__', '__delattr__','__doc__','__getattribute__', '__hash__', '__init__', '__module__','__name__','__new__', '__reduce__', '__reduce_ex__','__repr__', '__self__', '__setattr__','__str__']

因为内建函数(BIFs)和内建方法(BIMs)属于相同的类型,所以对BIF或者BIM 调用type()的结果都是:

>>> type(dir)
<type 'builtin_function_or_method'>

注意这不能应用于工厂函数,因为type()正好会返回产生对象的类型:

>>> type(int)
<type 'type'> >>> type(type)
<type 'type'>

b:用户定义的函数(UDF),通常是用python 写的,定义在模块的最高级,因此会作为全局名字空间的一部分装载到系统中。函数也可在其他的函数体内定义。

用户自定义函数属性如下表:

udf.__doc__

文档字符串(也可以用udf.func_doc)

udf.__name__

字符串类型的函数名字(也可以用 udf.func_name)

udf.func_code

字节编译的代码对象

udf.func_defaults

默认的参数元组

udf.func_globals

全局名字空间字典; 和从函数内部调用globals(x)一样

udf.func_dict

函数属性的名字空间

udf.func_doc

(见上面的udf.__doc__)

udf.func_name

(见上面的udf.__name__)

udf.func_closure

包含了自由变量的引用的单元对象元组(自用变量在UDF 中使用,但在别处定义)

用户自定义的函数是“函数“类型的,如:

>>> def foo(): pass
>>> type(foo)
<type 'function'>

c:通过lambda 来创建函数的对象除了没有命名之外,享有和用户自定义函数相同的属性;__name__或者func_name 属性给定为字符串"<lambda>":

>>> lambdaFunc = lambda x: x * 2
>>>type(lambdaFunc)
<type 'function'> >>> lambdaFunc.__name__
'<lambda>' 

一旦函数声明以后(且函数对象可用),程序员也可以自定义函数属性。所有的新属性变成udf.__dict__对象的一部分。

2:方法

a:内建方法(BIM)

内建方法的属性如下表:

bim.__doc__

文档字串

bim.__name__

字符串类型的函数名字

bim.__self__

绑定的对象

只有内建类型(BIT)有BIM。BIM 和BIF 两者也都享有相同属性。不同之处在于BIM 的__self__属性指向一个Python对象,而BIF 指向None:

>>> [1,2,3].append.__self__
[1,2,3]

对于内建方法,type()工厂函数给出了和BIF 相同的输出:

>>>type([].append)
<type'builtin_function_or_method'>

b:用户定义的方法(UDM)

UDM包含在类定义之中,无论UDM是否绑定,所有的UMD 都是相同的类型——“实例方法“,如下例:

>>> class C(object):
... def foo(self): pass
... >>> c = C() >>>type(C.foo)
<type'instancemethod'> >>> type(c.foo)
<type'instancemethod'>

下表展示了UDM的属性:

udm.__doc__

文档字符串

udm.__name__

字符串类型的方法名字(与umd.im_func.__name__相同)

udm.__module__

定义udm 的模块的名字(或none)

udm.im_class

方法相关联的类

udm.im_func

方法的函数对象(见UDFs)

udm.im_self

如果绑定的话为相关联的实例,如果非绑定位为none

3:类

“调用”类的结果便是创建了实例,即所谓的实例化。

4:类的实例

python 给类提供了名为__call__的特别方法,该方法允许程序员创建可调用的对象(实例)。

默认情况下,__call__()方法是没有实现的,这意味着大多数实例都是不可调用的。然而,如果在类定义中覆盖了这个方法,那么这个类的实例就成为可调用的了。调用这样的实例对象等同于调用__call__()方法。任何在实例调用中给出的参数都会被传入到__call()__中。例子如下:

>>> class C(object):
... def __call__(self, *args):
... print "I'm callable! Called with args:\n", args
...
>>> c = C()
>>> callable(c)
True
>>> c()
I'm callable! Called with arguments:
() >>> c(3, 'no more, no less')
I'm callable! Called with arguments:
(3, 'no more, no less')

二:代码对象

每个可调用对象的核心都是代码对象,由语句,赋值,表达式,以及其他可调用对象组成。

一般说来,代码对象可以作为函数或者方法调用的一部分来执行,也可用exec 语句或内建函数eval()来执行。

如果要执行python代码,那么该代码必须先要转换成字节编译的代码(又称字节码)。这才是真正的代码对象。然而,它们不包含任何关于它们执行环境的信息,这便是可调用对象存在的原因,它被用来包装一个代码对象并提供额外的信息。

函数对象仅是代码对象的包装,方法则是函数对象的包装。

 

三:可执行对象内建函数

1:callable

callable()是一个布尔函数,确定一个对象是否可以通过函数操作符(())来调用。如果函数可调用便返回True,否则便是False:

>>> callable(dir)           #内建函数
True >>> callable(1) #integer #整数
False >>> def foo(): pass
... >>> callable(foo) #用户自定义函数
True >>> callable('bar') #字符串
False >>> class C(object): pass
... >>> callable(C) #类
True

2:compile

compile()函数允许在运行时刻动态生成代码对象,然后就可以用exec语句或者内建函数eval()来执行这些对象或者对它们进行求值。

exec 和eval()都可以执行字符串格式的Python 代码。当执行字符串形式的代码时,每次都必须对这些代码进行字节编译处理。compile()函数提供了一次性字节代码预编译,以后每次调用的时候,都不用编译了。

compile 的三个参数都是必需的,第一参数代表了要编译的python代码。第二个字符串,虽然是必需的,但通常被置为空串。该参数代表了存放代码对象的文件的名字(字符串类型)。最后的参数是个字符串,它用来表明代码对象的类型。有三个可能值:’eval’, 'single', ’exec’

'eval' 可求值的表达式[和eval()一起使用],若第一个参数是语句的话,则会返回错误,比如:

>>> astr = "print'hello ,world'"
>>> compile(astr, '','eval')
Traceback (most recent calllast):
File "<stdin>", line 1, in <module>
File "", line 1
print 'hello ,world'
^
SyntaxError: invalid syntax 

'single' 单一可执行语句[和exec 一起使用],如果有多条语句的话,则只会编译第一句。

'exec' 可执行语句组[和exec 一起使用]。例子如下:

>>> eval_code = compile('100 + 200', '', 'eval')
>>> eval(eval_code)
300 >>> single_code = compile('print "Hello world!"', '','single')
>>> single_code
<code object ? at 120998, file "", line 0> >>> exec single_code
Hello world! >>> exec_code = compile("""
... req = input('Count how many numbers? ')
... for eachNum in range(req):
... print eachNum
... """, '', 'exec') >>> exec exec_code
Count how many numbers? 6
0
1
2
3
4
5

3:eval

eval()对表达式求值,不能处理语句。第一个参数可以为字符串或内建函数complie()创建的预编译代码对象。第二个和第三个参数,都为可选的,分别代表了全局和局部名字空间中的对象。如果给出这两个参数,globals 必须是个字典,locals可以是任意的映射对象。

如果都没给出这两个参数,分别默认为globals()和locals()返回的对象,如果只传入了一个全局字典,那么该字典也作为locals 传入。例子如下:

>>> eval('100 + 200')
300

在这种情况下,eval()接收一个字符串并把"100+200"作为表达式求值,当进行整数加法后,给出返回值300。

eval()函数的工作方式:对表达式两端的引号视而不见,接着假设“如果我是python 解释器,我会怎样去观察表达式呢?”,换句话说,如果以交互方式输入相同的表达式,解释器会做出怎么样的反应呢?按下回车后的结果应该和eval()返回的结果相同。

4:exec

exec 语句执行代码对象或字符串形式的python代码。类似地,用compile()预编译重复代码有助于改善性能。

exec 语句只接受一个参数,下面便是它的通用语法:exec obj

被执行的对象(obj)可以只是原始的字符串,比如单一语句或是语句组,它们也可以预编译成一个代码对象。例子如下:

>>> exec """
... x = 0
... print 'x is currently:', x
... while x < 5:
... x += 1
... print 'incrementing x to:', x
... """ x is currently: 0
incrementing x to: 1
incrementing x to: 2
incrementing x to: 3
incrementing x to: 4
incrementing x to: 5

exec 还可以接受有效的python 文件对象。如果我们用上面的多行代码创建一个叫xcount.py 的文件,那么也可以用下面的方法执行相同的代码:

>>> f = open('xcount.py')
>>> exec f
x is currently: 0
incrementing x to: 1
incrementing x to: 2
incrementing x to: 3
incrementing x to: 4
incrementing x to: 5

5:input

input()是eval()和raw_input()的组合,等价于eval(raw_input())。

类似于raw_input(),input()有一个可选的参数,该参数代表了给用户的字符串提示。该字符串默认为空串。

从功能上看,input 不同于raw_input(),因为raw_input()总是以字符串的形式,逐字地返回用户的输入。input()履行相同的的任务;而且,它还把输入作为python 表达式进行求值。这意味着input()返回的数据是对输入表达式求值的结果:一个python 对象。例子如下:

>>> aString = raw_input('Enter a list: ')
Enter a list: [ 123, 'xyz', 45.67 ] >>> aString
"[ 123, 'xyz', 45.67 ]" >>> type(aString)
<type 'str'> >>> aList = input('Enter a list: ')
Enter a list: [ 123, 'xyz', 45.67 ]
>>> aList
[123, 'xyz', 45.67]
>>> type(aList)
<type 'list'>

虽然用户输入字符串,但是input()把输入作为python 对象来求值并返回表达式的结果。

四:执行其他Python程序

1:execfile()

通过exec语句来读取python脚本的内容并执行,例子如下:

f = open(filename, 'r')
exec f
f.close() 

这3行可以调用execfile()来换掉:execfile(filename)

在某些情况下,可能需要用不同全局和局部的名字空间集合,而不是默认的集合来执行模块。execfile() 函数的语法非常类似于eval()函数的:

execfile(filename, globals=globals(), locals=locals())

类似eval(),globals 和locals 都是可选的,如果不提供参数值的话,默认为执行环境的名字空间。如果只给定globals,那么locals 默认和globals 相同。

2:将模块作为脚本执行

python2.4 里加入了一个新的命令行选项-m, 允许从shell 或DOS 提示符,直接把模块作为脚本来执行。

模块是标准库的一部分,安装在site-packages 里,或者仅仅是包里面的模块,那直接运行该模块脚本就不是那么容易了。比如,想运行免费的python web 服务器,以便创建和测试你自己的web 页面和CGI 脚本。则必须在命令行敲入如下的东西:

$ python /usr/local/lib/python2x/CGIHTTPServer.py
Serving HTTP on 0.0.0.0 port 8000 ...

如果它是第三方的,则不得不深入到site-packages 去找到它真正定位的地方。

如果不给出完全的路径名,可以用python -c
命令行开关,从命令行运行一个模块,并让python 的导入机制做这种跑腿工作:

$ python -c "import  CGIHTTPServer; CGIHTTPServer.test()"

该选项允许指定想要运行的python 语句。虽然这样可以工作,但是__name__模块不是‘__main__’,而是你正在使用的模块。解释器通过import 装载了你的模块,并不是它当作脚本。因此,所有在if __name__ == '__main__' 之下的代码是不会执行的,所以不得不手动地调用模块的test()函数。

要想同时要两者的优点——能够在类库中作为脚本执行模块,而不是作为导入的模块。这就是-m 参数的动机。现在可以像这样运行脚本:

$ python -m  CGIHTTPServer

五:执行其他非Python程序

也可以执行非python 程序。这些程序包括了二进制可执行文件,其他的shell 脚本等等。

1:os.system

一个非常简单的函数,接收字符串形式的系统命令并执行它。当执行命令的时候,python的运行是挂起的。当我们的执行完成之后,将会以system()的返回值形式给出退出状态,python 的执行也会继续。

system()保留了现有的标准文件,包括标准的输出,意味着执行任何的命令和程序显示输出都会传到标准输出上。

system()通常和不会产生输出的命令一起使用,通过退出状态显示成功或失败,0 表示成功,非零表示其他类型的错误。例子如下:

>>> import os
>>> result = os.system('cat /etc/motd') Have a lot of fun...
>>> result
0 >>> result = os.system('uname -a')
Linux solo 2.2.13 #1 Mon Nov 8 15:08:22 CET 1999 i586 unknown >>> result
0

六:结束执行

1:sys.exit() 和 SystemExit

立即退出程序并返回调用程序的主要方式是sys模块中的exit()函数。语法为:

sys.exit(status=0)

当调用sys.exit()时,就会引发systemExit()异常。除非对异常在一个try 语句和合适的except子句中进行捕获,否则解释器会用给定的状态参数退出,如果没有给出的话,该参数默认为0。

SystemExit 是唯一不看作错误的异常。它仅仅表示要退出python。

2:os.kill

os 模块的kill()函数模拟传统的unix函数来发送信号给进程。kill()参数是进程标识数(PID)和你想要发送到进程的信号。发送的典型信号为SIGINT、SIGQUIT或SIGKILL,来使进程终结。

Python基础:27执行环境的更多相关文章

  1. Python基础学习之环境搭建

    Python如今成为零基础编程爱好者的首选学习语言,这和Python语言自身的强大功能和简单易学是分不开的.今天我们将带领Python零基础的初学者完成入门的第一步——环境搭建.本文会先来区分几个在P ...

  2. 1. Python 基础概述 和 环境安装

    目录 Python 推荐书籍 开发环境 - Pyenv pyenv 使用 设置Python版本 virtualenv 虚拟环境 pip 通用配置 pip导出和导入 Jupyter 安装和配置 安装 j ...

  3. javascript基础进阶——执行环境及作用域链

    概念 执行环境 执行环境定义了变量或函数有权访问的其他函数,决定了他们各自的行为.每个执行环境都有一个与之关联的变量对象. 变量对象 环境中定义的所有变量和函数都保存在这个对象中. 全局执行环境 全局 ...

  4. python基础(27):类成员的修饰符、类的特殊成员

    1. 类成员的修饰符 类的所有成员在上一步骤中已经做了详细的介绍,对于每一个类的成员而言都有两种形式: 公有成员,在任何地方都能访问 私有成员,只有在类的内部才能方法 私有成员和公有成员的定义不同:私 ...

  5. Python基础---控制执行流程

    一.if语句 1.if语句 作用:让程序根据条件选择性地执行某条语句或某些语句 说明:if语句又叫条件语句,也叫分支语句 语法: if 真值表达式1: 语句块1 elif 真值表达式2: 语句块2 . ...

  6. python基础001----Python+pycharm环境搭建

    一.Python下载安装 1.python下载-----下载地址:https://www.python.org/downloads/windows/ 在python的官网下载python版本,需要下载 ...

  7. python基础27 -----python进程终结篇-----IO模型

    一.IO模型 1.IO模型分类 1.阻塞IO--------blocking IO 2.非阻塞IO------nonblocking IO 3. 多路复用IO------- multiplexing ...

  8. python网上开发执行环境

    http://www.tutorialspoint.com/execute_python_online.php

  9. python 模块的执行环境

随机推荐

  1. 验证码倒计时js

    getVarify.js // 验证码计时--第一种 window.onload = function () { var send = document.getElementById('send'), ...

  2. python枚举详解

    1. 枚举的定义 首先,定义枚举要导入enum模块. 枚举定义用class关键字,继承Enum类. 用于定义枚举的class和定义类的class是有区别[下一篇博文继续分享]. 示例代码: from ...

  3. 模拟4题解 T3奇袭

    T3奇袭 题目描述 由于各种原因,桐人现在被困在Under World(以下简称UW)中,而UW马上 要迎来最终的压力测试——魔界入侵. 唯一一个神一般存在的Administrator被消灭了,靠原本 ...

  4. 2018 8.8 提高A组模拟赛

    T1 Description 被污染的灰灰草原上有羊和狼.有N只动物围成一圈,每只动物是羊或狼. 该游戏从其中的一只动物开始,报出[1,K]区间的整数,若上一只动物报出的数是x,下一只动物可以报[x+ ...

  5. Thread.sleep

    Thread.sleep() The current thread changes state from Running to Waiting/Blocked as shown in the diag ...

  6. Python中输入和输出(打印)数据

    一个程序要进行交互,就需要进行输入,进行输入→处理→输出的过程.所以就需要用到输入和输出功能.同样的,在Python中,怎么实现输入和输出? Python3中的输入方式: Python提供了 inpu ...

  7. 洛谷 P1858 多人背包 DP

    目录 题面 题目链接 题目描述 输入输出格式 输入格式 输出格式 输入输出样例 输入样例 输出样例 说明 思路 AC代码 题面 题目链接 洛谷 P1858 多人背包 题目描述 求01背包前k优解的价值 ...

  8. MSSQL2008 数据压缩方法

    数据压缩功能使得SOL Server 2008允许在表.索引和分区中执行数据压缩,这样不仅可以节省磁盘空间,而且允许更多数据置入RAM中,从而提升数据库查询的性能. 1.启用行压缩 如果我们要在指定的 ...

  9. [Android]Space控件的应用场景

    Space控件是在Android 4.0中加入,是个空白的view,一般用于填充View组件中的间隙. support-v4包里提供了兼容低版本的Space控件. 源码分析 Space控件源码非常简单 ...

  10. 【JZOJ4921】【NOIP2017提高组模拟12.10】幻魔皇

    题目描述 幻魔皇拉比艾尔很喜欢斐波那契树,他想找到神奇的节点对. 所谓斐波那契树,根是一个白色节点,每个白色节点都有一个黑色节点儿子,而每个黑色节点则有一个白色和一个黑色节点儿子.神奇的节点对则是指白 ...