对于Windows 7 64位和psutil 5库上的Python 3.5。
我很困惑如何正确访问psutil.process_iter()返回的每个类“psutil.Process”项目中提供的名称和pid信息。
下面的代码返回一个类的“生成器”对象:
import psutil curProcesses = psutil.process_iter()
一个简单的循环输出包含在该生成器中的每个类“psutil.Process”对象:
for eachProcess in curProcesses: print(eachProcess)
OUTPUT:
psutil.Process(pid=0, name='System Idle Process') psutil.Process(pid=4, name='System') ... and so on ...
现在,这是我感到困惑的地方。
如果我修改前面的循环如下,那么我会得到一个整数PID和一个string名称 。
for eachProcess in curProcesses: # Observe the two different forms of access. print(eachProcess.pid) print(eachProcess.name())
OUTPUT:
0 System Idle Process 4 System ... and so on ...
结果整数和string正是我想要的。 但是,经过几次实验,我只能得到他们IF:
eachProcess.pid后面不加括号alaProcess.pid 。 (添加圆括号会产生一个TypeError:'int'对象不是可调用的exception。)
eachProcess.name后面加上括号alaProcess.name() 。 (删除圆括号会返回一个绑定的方法Process.name,而不是string的名称。)
为什么两个关键字参数pid和name的行为有所不同? (我怀疑我将要学习有关Python 3生成器对象的非常有用的东西…)
实际上没有太多: pid
是一个只读属性(用@property
装饰器创建),而name()
是一个方法,都是Process
类。 方法需要为了返回数据而调用parens,而在没有它们的情况下访问属性。 这一点的文件可能会有所帮助。 另外,如果你觉得有帮助,你可以看到name()
和pid
之间的实现有所不同。
至于为什么 pid
是Process
的只读属性,而需要调用方法name()
来获取进程名称,我不确定。 实际上, pid
似乎是进程类中唯一的只读属性,而有关进程实例的所有其他信息都是通过方法调用来检索的。 就个人而言,这样做似乎不一致/不标准,但我认为这是一个很好的理由。 我认为主要的原因是PID不能意外地改变,因为它是一个关键的组成部分。 如果PID是一种方法而不是只读属性,那么循环中的eachProcess.pid = 123
会将方法更改为int 123
,而按照当前的方式,此尝试的重新分配会引发错误,所以PID在某种意义上是受保护的,而eachProcess.name = 'foo'
可能会经过而不会引起错误。
另外请注意,虽然它们可能看起来像关键字参数,但它们出现在Process
类实例的字符串表示中, name()
和pid
不是关键字参数(尽管在创建Process
实例时, pid
可以作为关键字参数传递,但这不是发生在这里)。
我做了一个类的属性/属性主要是为了与subprocess.Popen.pid
进程保持一致subprocess.Popen.pid
和multiprocessing.Process.pid
stdlib模块(也是threading.Thread.ident
想到)。
而且,它不需要任何计算(与name()
, cmdline()
等相反),它永远不会改变,所以当时只读对我来说更有意义。
这是一个属性,而不仅仅是一个属性,只是在用户试图更改/设置的情况下出错。