2016-12-31 79 views
0

对于Windows 7 64位和psutil 5库上的Python 3.5。Python 3 psutil,提取pid和名称值?

我很困惑,如何正确地访问名字和每个类的psutil.Process“由psutil.process_iter()返回项目内提供的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和一个字符串

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 ... 

所得整数,字符串是我想要的东西。然而,经过多次实验,我只能让他们IF:

  • eachProcess.pid后面没有括号ALA eachProcess.pid。 (添加括号产生类型错误: 'INT' 对象不是可调用例外。)

  • eachProcess.name后跟括号的ala eachProcess.name()。 (删除括号返回绑定的方法Process.name代替的字符串名字。)

为什么这两个关键字寻找论据不同的pid的行为? (我怀疑我将要了解的Python 3发电机对象是非常有用的东西......)

回答

2

没有太多真的:pid是一个只读属性(与@property装饰创建),并name()是一种方法,都是Process这个类。为了返回数据,方法需要调用parens,而没有它们的情况下访问属性。 This bit of documentation可能会对您有所帮助。此外,如果您发现它有帮助,则可以看到name()pid之间的实施差异。

至于为什么pidProcess只读属性,而name()需要一种方法,以获取进程的名称叫,我不知道。事实上,pid似乎是进程类中唯一的只读属性,而有关流程实例的所有其他信息都是通过方法调用来检索的。就个人而言,这样做似乎不一致/不标准,但我认为这是一个很好的理由。我认为主要原因是PID不能意外改变,因为它是一个关键组成部分。如果PID是一种方法而不是只读属性,那么循环中的eachProcess.pid = 123会将方法更改为int 123,而按照当前的方式,此尝试的重新分配会引发错误,因此将保护PID从某种意义上说,虽然eachProcess.name = 'foo'可能会通过而不会产生错误。

另外,还要注意的是,虽然他们可能看起来像关键字参数在它们出现在Process类实例的字符串表示的方式name()pid不是关键字参数(尽管pid可以作为一个关键字参数创建Process时传递实例,但这不是发生在这里)。

+0

是否有一种直接的方式可以知道生成器对象中返回的not-really-keyword-argument是只读属性还是方法?或者,你必须走到比喻的窗帘后面,阅读图书馆的代码吗? (或者像我一样试验,直到发电机对象咳嗽出所需的信息。) – RBV

+1

@RBV你最好的选择总会是1)阅读文档,2)实验。我通常会先与#2一起去,然后再去#1,如果我不能通过实验来弄清楚它,那么反过来也可能更安全。总是最好先阅读文档。如果文档是好的,应该清楚某个方法或属性是什么,返回值是什么,参数是什么等等。上面为'psutil'链接的文档对您感兴趣的属性做了这些事情in。 – elethan

+1

如果一个属性写成一个不带参数的方法,而不是一个属性,这可能意味着它可能会做很多工作。属性的代码应该相当轻 - 不过比常规实例属性查找更多。例如,对于Windows上的'name',初始查找必须遍历系统上所有正在运行的进程的信息快照,直到它找到当前进程,因此它被实现为方法调用。 – eryksun

1

我制作了pid一个类属性/属性,主要是为了与subprocess.Popen.pidmultiprocessing.Process.pid stdlib模块保持一致(也出现了threading.Thread.ident)。

此外,这是不需要任何计算(从name(),cmdline()等相反),它永远不会改变,所以当时只读对我来说更有意义。

这是一个属性而不仅仅是一个属性,只是在用户尝试更改/设置时出错。