python核函数的调用 python调用多核

请教一个Python函数之间相互调用报错的问题Class A(): #class关键字首字母要小写
def GetEntryValues(): #类中的方法要添加self作为参数python核函数的调用,或者使用staticmethod声明成静态函数
InputValue = https://www.04ip.com/post/InputPath.get()
print InputValue
return InputValue
def OpenInputValue(): #类中的方法要添加self作为参数
print "sdsdsd"
GetEntryValues() #调用类中方法的时候python核函数的调用,如果是实例方法,需要使用self调用 , 如果是静态方法,需要类名调用
mainFrame = Tk()
frame1 = Frame(mainFrame)
frame1.pack()
InputPath = Entry(frame1)
InputPath.pack(side=LEFT)
GoButton = Button(frame1, text='open', command=OpenInputValue) #OpenInputValue是类中的方法,需要使用实例或者类名调用
GoButton.pack(side=LEFT)
mainFrame.mainloop()
我觉得你还是应该把python基础好好学习一下 。推荐看下python核心编程 。
如果解决了您的问题请采纳!
如果未解决请继续追问
python如何定义和调用函数1、函数定义
①使用def关键字定义函数

def 函数名(参数1.参数2.参数3...):
"""文档字符串,docstring , 用来说明函数的作用"""
#函数体
return 表达式
注释的作用:说明函数是做什么的,函数有什么功能 。
③遇到冒号要缩进 , 冒号后面所有的缩进的代码块构成了函数体,描述了函数是做什么的 , 即函数的功能是什么 。Python函数的本质与数学中的函数的本质是一致的 。
2、函数调用
①函数必须先定义,才能调用,否则会报错 。
②无参数时函数的调用:函数名(),有参数时函数的调用:函数名(参数1.参数2.……)
③不要在定义函数的时候在函数体里面调用本身,否则会出不来,陷入循环调用 。
④函数需要调用函数体才会被执行,单纯的只是定义函数是不会被执行的 。
⑤Debug工具中Step into进入到调用的函数里,Step Into My Code进入到调用的模块里函数 。
在Python中使用字符串调用函数已有字符串形式的函数名称,那么如何调用这个函数呢?
通过调用内置函数locals()和globals()返回的字典对象,就可以可以获得名称与对象的映射关系 。其中 , locals()仅在全局范围内调用时可以获得函数对象 。我们来看以下的例子 。
需要注意的是,使用上述方法通过字符串调用函数时,为了系统的安全 , 防止执行任意函数,需要对函数名做一些处理,也就是使用统一的前缀为这些函数命名 。例如在上述例子中,使用前缀cmd_ 函数名的形式定义函数(cmd_help,cmd_sum) 。
在传入函数名字符串时,只传入函数名的后半部分(如"help","sum"),由程序添加前缀后组成完整的函数名 , 再调用该函数 。
对于类的成员函数 , 则可以使用getattr()获得类成员函数 。
上述代码通过字符串调用了类成员函数,与前一段代码执行的结果相同 。
此外,还可以使用字典将字符串与函数对应起来调用 , 缺点就是每增加一个函数需要相应在字典对象中添加相应的键值,增加代码维护工作量 。
【python核函数的调用 python调用多核】以上代码在Python 3.6以上运行通过 。
python多线程对多核的利用GIL 与 Python 线程的纠葛
GIL 是什么东西?它对我们的 python 程序会产生什么样的影响?我们先来看一个问题 。运行下面这段 python 程序,CPU 占用率是多少?
# 请勿在工作中模仿 , 危险:)
def dead_loop():
while True:
pass
dead_loop()
答案是什么呢,占用 100% CPU?那是单核!还得是没有超线程的古董 CPU 。在我的双核 CPU 上,这个死循环只会吃掉我一个核的工作负荷,也就是只占用 50% CPU 。那如何能让它在双核机器上占用 100% 的 CPU 呢?答案很容易想到,用两个线程就行了,线程不正是并发分享 CPU 运算资源的吗 。可惜答案虽然对了,但做起来可没那么简单 。下面的程序在主线程之外又起了一个死循环的线程
import threading
def dead_loop():
while True:
pass
# 新起一个死循环线程
t = threading.Thread(target=dead_loop)
t.start()
# 主线程也进入死循环
dead_loop()
t.join()
按道理它应该能做到占用两个核的 CPU 资源,可是实际运行情况却是没有什么改变,还是只占了 50% CPU 不到 。这又是为什么呢?难道 python 线程不是操作系统的原生线程?打开 system monitor 一探究竟,这个占了 50% 的 python 进程确实是有两个线程在跑 。那这两个死循环的线程为何不能占满双核 CPU 资源呢?其实幕后的黑手就是 GIL 。
GIL 的迷思:痛并快乐着
GIL 的全称为 Global Interpreter Lock , 意即全局解释器锁 。在 Python 语言的主流实现 CPython 中,GIL 是一个货真价实的全局线程锁,在解释器解释执行任何 Python 代码时,都需要先获得这把锁才行,在遇到 I/O 操作时会释放这把锁 。如果是纯计算的程序,没有 I/O 操作,解释器会每隔 100 次操作就释放这把锁,让别的线程有机会执行(这个次数可以通过sys.setcheckinterval 来调整) 。所以虽然 CPython 的线程库直接封装操作系统的原生线程,但 CPython 进程做为一个整体,同一时间只会有一个获得了 GIL 的线程在跑,其它的线程都处于等待状态等着 GIL 的释放 。这也就解释了我们上面的实验结果:虽然有两个死循环的线程,而且有两个物理 CPU 内核,但因为 GIL 的限制 , 两个线程只是做着分时切换,总的 CPU 占用率还略低于 50% 。
看起来 python 很不给力啊 。GIL 直接导致 CPython 不能利用物理多核的性能加速运算 。那为什么会有这样的设计呢?我猜想应该还是历史遗留问题 。多核 CPU 在 1990 年代还属于类科幻,Guido van Rossum 在创造 python 的时候,也想不到他的语言有一天会被用到很可能 1000+ 个核的 CPU 上面,一个全局锁搞定多线程安全在那个时代应该是最简单经济的设计了 。简单而又能满足需求,那就是合适的设计(对设计来说 , 应该只有合适与否 , 而没有好与不好) 。怪只怪硬件的发展实在太快了,摩尔定律给软件业的红利这么快就要到头了 。短短 20 年不到,代码工人就不能指望仅仅靠升级 CPU 就能让老软件跑的更快了 。在多核时代,编程的免费午餐没有了 。如果程序不能用并发挤干每个核的运算性能,那就意谓着会被淘汰 。对软件如此,对语言也是一样 。那 Python 的对策呢?
Python 的应对很简单,以不变应万变 。在最新的 python 3 中依然有 GIL 。之所以不去掉,原因嘛,不外以下几点:
欲练神功,挥刀自宫:
CPython 的 GIL 本意是用来保护所有全局的解释器和环境状态变量的 。如果去掉 GIL,就需要多个更细粒度的锁对解释器的众多全局状态进行保护 。或者采用 Lock-Free 算法 。无论哪一种,要做到多线程安全都会比单使用 GIL 一个锁要难的多 。而且改动的对象还是有 20 年历史的 CPython 代码树,更不论有这么多第三方的扩展也在依赖 GIL 。对 Python 社区来说,这不异于挥刀自宫 , 重新来过 。
就算自宫 , 也未必成功:
有位牛人曾经做了一个验证用的 CPython,将 GIL 去掉 , 加入了更多的细粒度锁 。但是经过实际的测试,对单线程程序来说 , 这个版本有很大的性能下降,只有在利用的物理 CPU 超过一定数目后,才会比 GIL 版本的性能好 。这也难怪 。单线程本来就不需要什么锁 。单就锁管理本身来说 , 锁 GIL 这个粗粒度的锁肯定比管理众多细粒度的锁要快的多 。而现在绝大部分的 python 程序都是单线程的 。再者,从需求来说,使用 python 绝不是因为看中它的运算性能 。就算能利用多核,它的性能也不可能和 C/C比肩 。费了大力气把 GIL 拿掉,反而让大部分的程序都变慢了,这不是南辕北辙吗 。
难道 Python 这么优秀的语言真的仅仅因为改动困难和意义不大就放弃多核时代了吗?其实,不做改动最最重要的原因还在于:不用自宫,也一样能成功!
其它神功
那除了切掉 GIL 外,果然还有方法让 Python 在多核时代活的滋润?让我们回到本文最初的那个问题:如何能让这个死循环的 Python 脚本在双核机器上占用 100% 的 CPU?其实最简单的答案应该是:运行两个 python 死循环的程序!也就是说,用两个分别占满一个 CPU 内核的 python 进程来做到 。确实,多进程也是利用多个 CPU 的好方法 。只是进程间内存地址空间独立,互相协同通信要比多线程麻烦很多 。有感于此,Python 在 2.6 里新引入了 multiprocessing这个多进程标准库 , 让多进程的 python 程序编写简化到类似多线程的程度,大大减轻了 GIL 带来的不能利用多核的尴尬 。
这还只是一个方法,如果不想用多进程这样重量级的解决方案,还有个更彻底的方案,放弃 Python,改用 C/C。当然,你也不用做的这么绝 , 只需要把关键部分用 C/C写成 Python 扩展 , 其它部分还是用 Python 来写,让 Python 的归 Python,C 的归 C 。一般计算密集性的程序都会用 C 代码编写并通过扩展的方式集成到 Python 脚本里(如 NumPy 模块) 。在扩展里就完全可以用 C 创建原生线程,而且不用锁 GIL , 充分利用 CPU 的计算资源了 。不过 , 写 Python 扩展总是让人觉得很复杂 。好在 Python 还有另一种与 C 模块进行互通的机制 : ctypes
利用 ctypes 绕过 GIL
ctypes 与 Python 扩展不同,它可以让 Python 直接调用任意的 C 动态库的导出函数 。你所要做的只是用 ctypes 写些 python 代码即可 。最酷的是 , ctypes 会在调用 C 函数前释放 GIL 。所以,我们可以通过 ctypes 和 C 动态库来让 python 充分利用物理内核的计算能力 。让我们来实际验证一下,这次我们用 C 写一个死循环函数
extern"C"
{
void DeadLoop()
{
while (true);
}
}
用上面的 C 代码编译生成动态库 libdead_loop.so (Windows 上是 dead_loop.dll)
,接着就要利用 ctypes 来在 python 里 load 这个动态库,分别在主线程和新建线程里调用其中的 DeadLoop
from ctypes import *
from threading import Thread
lib = cdll.LoadLibrary("libdead_loop.so")
t = Thread(target=lib.DeadLoop)
t.start()
lib.DeadLoop()
这回再看看 system monitor , Python 解释器进程有两个线程在跑 , 而且双核 CPU 全被占满了,ctypes 确实很给力!需要提醒的是,GIL 是被 ctypes 在调用 C 函数前释放的 。但是 Python 解释器还是会在执行任意一段 Python 代码时锁 GIL 的 。如果你使用 Python 的代码做为 C 函数的 callback,那么只要 Python 的 callback 方法被执行时,GIL 还是会跳出来的 。比如下面的例子:
extern"C"
{
typedef void Callback();
void Call(Callback* callback)
{
callback();
}
}
from ctypes import *
from threading import Thread
def dead_loop():
while True:
pass
lib = cdll.LoadLibrary("libcall.so")
Callback = CFUNCTYPE(None)
callback = Callback(dead_loop)
t = Thread(target=lib.Call, args=(callback,))
t.start()
lib.Call(callback)
注意这里与上个例子的不同之处,这次的死循环是发生在 Python 代码里 (DeadLoop 函数) 而 C 代码只是负责去调用这个 callback 而已 。运行这个例子,你会发现 CPU 占用率还是只有 50% 不到 。GIL 又起作用了 。
其实,从上面的例子 , 我们还能看出 ctypes 的一个应用,那就是用 Python 写自动化测试用例,通过 ctypes 直接调用 C 模块的接口来对这个模块进行黑盒测试,哪怕是有关该模块 C 接口的多线程安全方面的测试,ctypes 也一样能做到 。
结语
虽然 CPython 的线程库封装了操作系统的原生线程,但却因为 GIL 的存在导致多线程不能利用多个 CPU 内核的计算能力 。好在现在 Python 有了易经筋(multiprocessing), 吸星大法(C 语言扩展机制)和独孤九剑(ctypes) , 足以应付多核时代的挑战,GIL 切还是不切已经不重要了,不是吗 。
Python中怎样编写混合核函数?这个和用不用python没啥关系,是数据来源的问题 。调用淘宝API,使用 api相关接口获得你想要的内容,我 记得api中有相关的接口 , 你可以看一下接口的说明 。用python做爬虫来进行页面数据的获龋 。
核心解密Python函数在(类与函数之间)和(类与类之间)互相调用 首先来看一个函数间的调用
类方法:
执行结果:
metaclass能有什么用处,先来个感性的认识:
1.1 在wiki上面,metaclass是这样定义的:In object-oriented programming,
a metaclass is a class whose instances are classes.
Just as an ordinary class defines the behavior of certain objects,
a metaclass defines the behavior of certain classes and their instances.
也就是说metaclass的实例化结果是类 , 而class实例化的结果是instance 。我是这么理解的:
metaclass是类似创建类的模板,所有的类都是通过他来create的(调用 new ),这使得你可以自由的控制
创建类的那个过程,实现你所需要的功能 。
当然你也可以用函数的方式(下文会讲)
4.1 用类的形式
4.1.1 类继承于type, 例如: class Meta(type):pass
4.1.2 将需要使用metaclass来构建class的类的 metaclass 属性(不需要显示声明,直接有的了)赋值为Meta(继承于type的类)
4.2 用函数的形式
4.2.1 构建一个函数,例如叫metaclass_new, 需要3个参数:name, bases, attrs,
name: 类的名字
bases: 基类,通常是tuple类型
attrs: dict类型,就是类的属性或者函数
4.2.2 将需要使用metaclass来构建class的类的 metaclass 属性(不需要显示声明,直接有的了)赋值为函数metaclas_new
5.1 basic
metaclass的原理其实是这样的:当定义好类之后,创建类的时候其实是调用了type的 new 方法为这个类分配内存空间,创建
好了之后再调用type的 init 方法初始化(做一些赋值等) 。所以metaclass的所有magic其实就在于这个 new 方法里面了 。
说说这个方法: new (cls, name, bases, attrs)
cls: 将要创建的类,类似与self,但是self指向的是instance , 而这里cls指向的是class
name: 类的名字,也就是我们通常用类名. name 获取的 。
bases: 基类
attrs: 属性的dict 。dict的内容可以是变量(类属性) , 也可以是函数(类方法) 。
所以在创建类的过程,我们可以在这个函数里面修改name,bases , attrs的值来自由的达到我们的功能 。这里常用的配合方法是
getattr和setattr(just an advice)
下面实现python中在一个类中调用另一个类的函数方法
或者下面来一个号理解的例子
执行结果:
先来介绍内部类与外部类是什么?
看源码解析:
内部类调用外部类的类属性和类方法
参考文献1
参考文献2
参考文献3
python核函数的调用的介绍就聊到这里吧 , 感谢你花时间阅读本站内容,更多关于python调用多核、python核函数的调用的信息别忘了在本站进行查找喔 。

    推荐阅读