For Python 3.5 on Windows 7 64-bit and the psutil 5 library.
I'm confused as to how to properly access the name and pid information provided within each class 'psutil.Process' item returned by psutil.process_iter().
The following code returns a class 'generator' object:
import psutil
curProcesses = psutil.process_iter()
A simple loop outputs each class 'psutil.Process' object contained within that generator:
for eachProcess in curProcesses:
print(eachProcess)
OUTPUT:
psutil.Process(pid=0, name='System Idle Process')
psutil.Process(pid=4, name='System')
... and so on ...
Now here's where I'm getting confused.
IF I modify the previous loop as follows, THEN I'll get an integer pid and a string name.
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 ...
The resulting integer and string are exactly what I want. However, after several experiments I can only get them IF:
eachProcess.pid is NOT followed by parentheses ala eachProcess.pid. (Adding parentheses produces a TypeError: 'int' object is not callable exception.)
eachProcess.name is followed by parentheses ala eachProcess.name(). (Removing the parentheses returns a bound method Process.name instead of the name as a string.)
Why do the two keyword-looking arguments pid and name behave differently? (I suspect I'm about to learn something very useful about Python 3 generator objects...)
There is not much to it really:
pid
is a read-only attribute (created with the@property
decorator), andname()
is a method, both of theProcess
class. Methods need parens to be called in order to return data, while attributes are accessed without them. This bit of documentation might be helpful. Also, if you find it helpful, you can see the difference in implementation betweenname()
andpid
.As far as why
pid
is a read-only attribute ofProcess
, while a methodname()
needs to be called in order to get the process name, I am not sure. In fact,pid
appears to be the only read-only attrubute on the process class, while all other information about the process instance is retrieved through method calls. Personally it seems inconsistent/non-standard to do it this way, but I assume that there is a good reason for this choice. I assume the main reason is so the PID cannot be changed accidentally since it is a crucial component. If the PID were a method instead of a read-only attribute, theneachProcess.pid = 123
in your loop would change the method to the int123
, while the way it currently is, this attempted reassignment will raise an error instead, so that the PID is protected in a sense, whileeachProcess.name = 'foo'
will probably go by without raising an error.Also, note that while they may look like keyword arguments in the way they appear in the string representations of
Process
class instances,name()
andpid
are not keyword arguments (althoughpid
can be passed as a keyword argument when creating aProcess
instance, but that is not what is happening here).