大家好,又见面了,我是你们的朋友全栈君。
psutil release. The reason? I’ve been travelling! I mean… a lot. I’ve spent 3 months in Berlin, 3 weeks in Japan and 2 months in New York City. While I was there I finally had the chance to meet my friend
Jay Loden in person.
Jay and I originally started working on psutil together
7 years ago.
一版
psutil发布以来已经有很长时间了。 原因? 我一直在旅行! 我的意思是……很多。 我在柏林呆了3个月,在日本呆了3个星期,在纽约呆了2个月。 当我在那里的时候,我终于有机会亲自见到我的朋友
杰伊·洛登 。
我和Jay最初
7年前开始一起从事psutil的研究。
Back then I didn’t know any C (and I still am a terrible C developer) so he’s been crucial to develop the initial psutil skeleton including OSX and Windows support. I’m back home now (but not for long ;-)), so I finally have some time to write this blog post and tell you about the new psutil release. Let’s see what happened.
那时我还不懂C(而且我仍然是一个糟糕的C开发人员),所以他对于开发包括OSX和Windows支持的初始psutil框架至关重要。 我现在回到家了(但时间不长;-)),所以我终于有时间写这篇博客文章,并向您介绍新的psutil版本。 让我们来看看发生了什么。
net_if_addrs() ( net_if_addrs())
In a few words, we’re now able to list network interface addresses similarly to “ifconfig” command on UNIX:
简而言之,我们现在可以列出网络接口地址,类似于UNIX上的“ ifconfig”命令:
>>> import psutil
>>> psutil.net_if_addrs()
{'eth0': [snic(
family=<AddressFamily.AF_INET: 2>,
address='10.0.0.4',
netmask='255.0.0.0',
broadcast='10.255.255.255'),
snic(
family=<AddressFamily.AF_PACKET: 17>,
address='9c:eb:e8:0b:05:1f',
netmask=None,
broadcast='ff:ff:ff:ff:ff:ff')],
'lo': [snic(
family=<AddressFamily.AF_INET: 2>,
address='127.0.0.1',
netmask='255.0.0.0',
broadcast='127.0.0.1'),
snic(
family=<AddressFamily.AF_PACKET: 17>,
address='00:00:00:00:00:00',
netmask=None,
broadcast='00:00:00:00:00:00')]}
This is limited to AF_INET (IPv4), AF_INET6 (IPv6) and AF_LINK (ETHERNET) address families. If you want something more poweful (e.g. AF_BLUETOOTH) you can take a look at netifaces extension. And here’s the code which does these tricks on POSIX and Windows:
这仅限于AF_INET(IPv4),AF_INET6(IPv6)和AF_LINK(ETHERNET)地址族。 如果您想要更强大的功能(例如AF_BLUETOOTH),可以看看netifaces扩展。 这是在POSIX和Windows上执行这些技巧的代码:
Also, here’s some doc.
另外,这是一些文档 。
net_if_stats() ( net_if_stats())
This will return a bunch of information about network interface cards:
这将返回一堆有关网络接口卡的信息:
>>> import psutil
>>> psutil.net_if_stats()
{'eth0': snicstats(
isup=True,
duplex=<NicDuplex.NIC_DUPLEX_FULL: 2>,
speed=100,
mtu=1500),
'lo': snicstats(
isup=True,
duplex=<NicDuplex.NIC_DUPLEX_UNKNOWN: 0>,
speed=0,
mtu=65536)}
Again, here’s the code:
同样,这是代码:
…and the doc.
…和文件 。
枚举 ( Enums)
Enums are a nice new feature introduced in Python 3.4. Very briefly (or at least, this is what I appreciate the most about them), they help you write an API with human-readable constants. If you use Python 2 you’ll see something like this:
枚举是Python 3.4中引入的一项不错的新功能。 非常简短(或者至少,这是我最欣赏的),它们可以帮助您编写具有人类可读常量的API。 如果您使用Python 2,则会看到以下内容:
>>> import psutil
>>> psutil.IOPRIO_CLASS_IDLE
3
On Python 3.4 you’ll see a more informative:
在Python 3.4上,您会看到更多信息:
>>> import psutil
>>> psutil.IOPRIO_CLASS_IDLE
<IOPriority.IOPRIO_CLASS_IDLE: 3>
They are backward compatible, meaning if you’re sending serialized data produced with psutil through the network you can safely use comparison operators and so on. The psutil APIs returning enums (on Python >=3.4) are:
它们是向后兼容的,这意味着如果您要通过网络发送由psutil生成的序列化数据,则可以安全地使用比较运算符等。 返回枚举的psutil API(在Python> = 3.4上)是:
- psutil.net_connections() (the address families):
- psutil.Process.connections() (same as above)
- psutil.net_if_stats() (all NIC_DUPLEX_* constants)
- psutil.Process.nice() on Windows (for all the *_PRIORITY_CLASS constants)
- psutil.Process.ionice() on Linux (for all the IOPRIO_CLASS_* constants)
- psutil.net_connections() (地址族):
- psutil.Process.connections() (与上面相同)
- psutil.net_if_stats() (所有NIC_DUPLEX_ *常量)
- Windows上的psutil.Process.nice() (用于所有* _PRIORITY_CLASS常量)
- Linux上的psutil.Process.ionice() (用于所有IOPRIO_CLASS_ *常量)
All the other existing constants remained plain strings (STATUS_*) or integers (CONN_*).
所有其他现有常量仍为纯字符串( STATUS_ * )或整数( CONN_ * )。
僵尸进程 ( Zombie processes)
This is a big one. The full story is here but basically the support for zombie processes on UNIX was broken (except on Linux – Windows doesn’t have zombie processes). Up until psutil 2.* we could instantiate a zombie process:
这是一个很大的。 完整的故事就在这里,但是从根本上来说,UNIX对僵尸进程的支持已被破坏 (Linux除外-Windows没有僵尸进程)。 直到psutil 2. *,我们才能实例化一个僵尸进程:
>>> pid = create_zombie()
>>> p = psutil.Process(pid)
…but every time we queried it we got a NoSuchProcess exception:
…但是每次我们查询时,我们都会遇到一个NoSuchProcess异常:
>>> psutil.name()
File "psutil/__init__.py", line 374, in _init
raise NoSuchProcess(pid, None, msg)
psutil.NoSuchProcess: no process found with pid 123
That was misleading though because the PID technically still existed:
但这有误导性,因为技术上PID仍然存在:
>>> psutil.pid_exists(p.pid)
True
Furthermore, depending on what platform you were on, certain process stats could still be queried (instead of raising NoSuchProcess):
此外,根据您所使用的平台,仍然可以查询某些过程统计信息(而不是引发NoSuchProcess ):
>>> psutil.cmdline()
['python']
Also process_iter() did not return zombie processes at all. This was probably the worst aspect because being able to identify them is an important use case, as they signal an issue with process: if a parent process spawns a child, terminates it (via kill()), but doesn’t wait() for it it will create a zombie. Long story short, the way this changed in psutil 3.0 is that:
而且process_iter()根本没有返回僵尸进程。 这可能是最糟糕的方面,因为能够识别它们是一个重要的用例,因为它们表明流程存在问题:如果父流程产生了一个孩子,则终止它(通过kill() ),但不等待()为此它将创建一个僵尸。 长话短说,在psutil 3.0中更改的方式是:
- we now have a new ZombieProcess exception, raised every time we’re not able to query a process because it’s a zombie
- it is raised instead of NoSuchProcess (which was incorrect and misleading)
- it is still backward compatible (meaning you won’t have to change your old code) because it inherits from NoSuchProcess
- process_iter() finally works, meaning you can safely identify zombie processes like this:
- 我们现在有了一个新的ZombieProcess异常,每次我们无法查询某个流程时都会引发该异常,因为它是一个僵尸
- 它被引发而不是NoSuchProcess (这是不正确的并且具有误导性)
- 它仍然向后兼容(这意味着您不必更改旧代码),因为它继承自NoSuchProcess
- process_iter()终于可以工作了,这意味着您可以安全地标识如下僵尸进程:
import psutil
zombies = []
for p in psutil.process_iter():
try:
if p.status() == psutil.STATUS_ZOMBIE:
zombies.append(p)
except NoSuchProcess:
pass
删除不推荐使用的API ( Removal of deprecated APIs)
This is another big one, probably the biggest. In a previous blog post I already talked about deprecated APIs. What I did back then (January 2014) was to rename and officially deprecate different APIs and provide aliases for them so that people wouldn’t yell at me because I broke their existent code. The most interesting deprecation was certainly the one affecting module constants and the hack which was used in order to provide “module properties”. With this new release I decided to get rid of all those aliases. I’m sure this will cause problems but hey! This is a new major release, right? =). Plus the amount of crap which was removed is impressive (see the commit). Here’s the old aliases which are now gone for good (or bad, depending on how much headache they will cause you):
这是另一个大的,也许是最大的。 在先前的博客文章中,我已经讨论过时的API 。 我当时(2014年1月)所做的就是重命名并正式弃用了不同的API,并为它们提供了别名,这样人们就不会因为我破坏了它们的现有代码而对我大喊大叫。 最有趣的弃用当然是影响模块常量的一种弃用,它是为了提供“模块属性”而使用的。 在这个新版本中,我决定摆脱所有这些别名。 我敢肯定这会引起问题,但是嘿! 这是新的主要版本,对吗? =)。 加上被删除的废话数量令人印象深刻(请参阅commit )。 这是旧的别名,这些别名现在已一去不复返了(或坏了,取决于它们会给您带来多大的麻烦):
Removed module functions and constants
删除了模块功能和常量
Already deprecated name | 已弃用的名称 | New name | 新名字 |
---|---|---|---|
psutil.BOOT_TIME() | psutil.BOOT_TIME() | psutil.boot_time() | psutil.boot_time() |
psutil.NUM_CPUS() | psutil.NUM_CPUS() | psutil.cpu_count() | psutil.cpu_count() |
psutil.TOTAL_PHYMEM() | psutil.TOTAL_PHYMEM() | psutil.virtual_memory().total | psutil.virtual_memory()。总计 |
psutil.avail_phymem() | psutil.avail_phymem() | psutil.virtual_memory().free | psutil.virtual_memory()。free |
psutil.avail_virtmem() | psutil.avail_virtmem() | psutil.swap_memory().free | psutil.swap_memory()。free |
psutil.cached_phymem() (Linux only) | psutil.cached_phymem()(仅Linux) | psutil.virtual_memory().cached | psutil.virtual_memory()。cached |
psutil.get_pid_list() | psutil.get_pid_list() | psutil.pids().cached | psutil.pids()。cached |
psutil.get_process_list() | psutil.get_process_list() | – | – |
psutil.get_users() | psutil.get_users() | psutil.users() | psutil.users() |
psutil.network_io_counters() | psutil.network_io_counters() | psutil.net_io_counters() | psutil.net_io_counters() |
psutil.phymem_buffers() (Linux only) | psutil.phymem_buffers()(仅Linux) | psutil.virtual_memory().buffers | psutil.virtual_memory()。buffers |
psutil.phymem_usage() | psutil.phymem_usage() | psutil.virtual_memory() | psutil.virtual_memory() |
psutil.total_virtmem() | psutil.total_virtmem() | psutil.swap_memory().total | psutil.swap_memory()。总计 |
psutil.used_virtmem() | psutil.used_virtmem() | psutil.swap_memory().used | psutil.swap_memory()。使用 |
psutil.used_phymem() | psutil.used_phymem() | psutil.virtual_memory().used | psutil.virtual_memory()。使用 |
psutil.virtmem_usage() | psutil.virtmem_usage() | psutil.swap_memory() | psutil.swap_memory() |
Process methods (assuming p = psutil.Process()):
处理方法(假设p = psutil.Process()):
Already deprecated name | 已弃用的名称 | New name | 新名字 |
---|---|---|---|
p.get_children() | p.get_children() | p.children() | p.children() |
p.get_connections() | p.get_connections() | p.connections() | p.connections() |
p.get_cpu_affinity() | p.get_cpu_affinity() | p.cpu_affinity() | p.cpu_affinity() |
p.get_cpu_percent() | p.get_cpu_percent() | p.cpu_percent() | p.cpu_percent() |
p.get_cpu_times() | p.get_cpu_times() | p.cpu_times() | p.cpu_times() |
p.get_io_counters() | p.get_io_counters() | p.io_counters() | p.io_counters() |
p.get_ionice() | p.get_ionice() | p.ionice() | p.ionice() |
p.get_memory_info() | p.get_memory_info() | p.memory_info() | p.memory_info() |
p.get_ext_memory_info() | p.get_ext_memory_info() | p.memory_info_ex() | p.memory_info_ex() |
p.get_memory_maps() | p.get_memory_maps() | p.memory_maps() | p.memory_maps() |
p.get_memory_percent() | p.get_memory_percent() | p.memory_percent() | p.memory_percent() |
p.get_nice() | p.get_nice() | p.nice() | p.nice() |
p.get_num_ctx_switches() | p.get_num_ctx_switches() | p.num_ctx_switches() | p.num_ctx_switches() |
p.get_num_fds() | p.get_num_fds() | p.num_fds() | p.num_fds() |
p.get_num_threads() | p.get_num_threads() | p.num_threads() | p.num_threads() |
p.get_open_files() | p.get_open_files() | p.open_files() | p.open_files() |
p.get_rlimit() | p.get_rlimit() | p.rlimit() | p.rlimit() |
p.get_threads() | p.get_threads() | p.threads() | p.threads() |
p.getcwd() | p.getcwd() | p.cwd() | p.cwd() |
p.set_cpu_affinity() | p.set_cpu_affinity() | p.cpu_affinity() | p.cpu_affinity() |
p.set_ionice() | p.set_ionice() | p.ionice() | p.ionice() |
p.set_nice() | p.set_nice() | p.nice() | p.nice() |
p.set_rlimit() | p.set_rlimit() | p.rlimit() | p.rlimit() |
If your code suddenly breaks with AttributeError after you upgraded psutil it means you were using one of those deprecated aliases. In that case just take a look at the table above and rename stuff in accordance.
如果您的代码在升级psutil后突然因AttributeError中断,则意味着您正在使用那些已弃用的别名之一。 在这种情况下,只需看一下上表并按照相应的名称重命名即可。
Bug修复 ( Bug fixes)
I fixed a lot of stuff (full list here), but here’s the list of things which I think are worth mentioning:
我修复了很多东西(完整列表在此处 ),但这是我认为值得一提的东西列表:
- #512: [FreeBSD] fix segfault in net_connections().
- #593: [FreeBSD] Process.memory_maps() segfaults.
- #606: Process.parent() may swallow NoSuchProcess exceptions.
- #614: [Linux]: cpu_count(logical=False) return the number of physical CPUs instead of physical cores.
- #628: [Linux] Process.name() truncates process name in case it contains spaces or parentheses.
- #512 :[FreeBSD]修复了net_connections()中的段错误 。
- #593 :[FreeBSD] Process.memory_maps()段错误 。
- #606 : Process.parent()可能吞下NoSuchProcess异常。
- #614 :[Linux]: cpu_count(logical = False)返回物理CPU的数量,而不是物理核心的数量。
- #628 :[Linux] Process.name()在包含空格或括号的情况下会截断进程名称。
易于发展 ( Ease of development)
These are not enhancements you will directly benefit from but I put some effort into making my life easier every time I work on psutil.
这些并不是您可以直接受益的增强功能,但是每次使用psutil时,我都会付出一些努力来简化生活。
- I care about psutil code being fully PEP8 compliant so I added a pre-commit GIT hook which runs flake8 on every commit and rejects it if the coding style is not compliant. The way I install this is via make install-git-hooks.
- I added a make install-dev-deps command which installs all deps and stuff which is useful for testing (ipdb, coverage, etc).
- A new make coverage command which runs coverage. With this I discovered some of parts in the code which weren’t covered by tests and I fixed that.
- I started using tox to easily test psutil against all supported Python versions (from 2.6 to 3.4) in one shot.
- I reorganized tests so that now they can be easily executed with py.test and nose (before, only unittest runner was fully supported)
- 我关心psutil代码是否完全符合PEP8规范,因此我添加了一个预提交GIT挂钩 ,该挂钩在每次提交时都运行flake8 ,如果编码风格不兼容,则拒绝它。 我的安装方法是通过make install-git-hooks 。
- 我添加了一个make install-dev-deps命令,该命令将安装所有可用于测试的部门和内容(ipdb,覆盖率等)。
- 一个新的make coverage命令,用于运行coverage 。 有了这个,我发现了代码中一些未被测试覆盖的部分,我对此进行了修复。
- 我开始使用tox轻松地针对所有受支持的Python版本(从2.6到3.4)测试psutil。
- 我重新组织了测试,以便现在可以使用py.test和鼻子轻松地执行它们(之前,仅完全支持unittest运行器)
最后的话 ( Final words)
800.000 download a month, which is pretty great for a Python library. As of right now I consider psutil almost “completed” in terms of features, meaning I’m basically running out of ideas on what I should add next (see
TODO). From now on the future development will probably focus on adding support for more exotic platforms (
OpenBSD,
NetBSD,
Android). There also have been some discussions on python-ideas mailing list about
including psutil into Python stdlib but, assuming that will ever happen, it’s still far away in the future as it would require a lot of time which I currently don’t have. That should be all. I hope you will all enjoy this new release.
每个月下载将近
800.000 ,对于Python库而言,这是非常不错的。 截至目前,我认为psutil在功能方面几乎“完成”,这意味着我基本上对接下来应该添加的内容已经用尽了(请参阅
TODO )。 从现在开始,未来的发展可能会集中在增加对更多异国平台(
OpenBSD ,
NetBSD ,
Android )的支持上。 在python-ideas邮件列表上也进行了一些讨论,涉及
将psutil包含到Python stdlib中,但是,假设这会发生,那么它仍然遥遥无期,因为它需要很多时间,而我目前没有。 那应该是全部。 希望大家都喜欢这个新版本。
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/132567.html原文链接:https://javaforall.cn
【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛
【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...