usb 2.2.0移植
This my second blog post is going to be about psutil 2.0, a major release in which I decided to reorganize the existing API for the sake of consistency. At the time of writing psutil 2.0 is still under development and the intent of this blog post is to serve as an official reference which describes how you should port your existent code base. In doing so I will also explain why I decided to make these changes. Despite many APIs will still be available as aliases pointing to the newer ones, the overall changes are numerous and many of them are not backward compatible. I’m sure many people will be sorely bitten but I think this is for the better and it needed to be done, hopefully for the first and last time. OK, here we go now.
我的第二篇博文将涉及psutil 2.0 ,这是一个主要发行版,为了保持一致性,我决定在其中重新组织现有的API 。 在撰写本文时,psutil 2.0仍在开发中,此博客文章的目的是用作正式参考,它描述了如何移植现有的代码库。 通过这样做,我还将解释为什么我决定进行这些更改。 尽管仍有许多API可以用作指向较新API的别名 ,但总体变化很多,其中许多不向后兼容 。 我相信很多人都会被咬伤,但是我认为这是更好的方法,需要做,希望是第一次也是最后一次。 好的,我们现在开始。
模块常量变成函数 (Module constants turned into functions)
什么改变了 (What changed)
Old name | 旧名 | Replacement | 替代 |
---|---|---|---|
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()。总计 |
我为什么做 (Why I did it)
I already talked about this more extensively in this blog post. In short: other than introducing unnecessary slowdowns, calculating a module level constant at import time is dangerous because in case of error the whole app will crash. Also, the represented values may be subject to change (think about the system clock) but the constant cannot be updated.Thanks to this hack accessing the old constants still works and produces a DeprecationWarning.
我已经在这篇博客文章中对此进行了更广泛的讨论。 简而言之:除了引入不必要的速度降低之外,在导入时计算模块级别常量是很危险的,因为如果发生错误,整个应用程序将会崩溃。 同样,表示的值可能会发生变化(考虑系统时钟),但无法更新常量。由于这种黑客行为,访问旧常量仍然有效,并且会产生DeprecationWarning 。
模块功能重命名 (Module functions renamings)
什么改变了 (What changed)
Old name | 旧名 | Replacement | 替代 |
---|---|---|---|
psutil.get_boot_time() | psutil.get_boot_time() | psutil.boot_time() | psutil.boot_time() |
psutil.get_pid_list() | psutil.get_pid_list() | psutil.pids() | psutil.pids() |
psutil.get_users() | psutil.get_users() | psutil.users() | psutil.users() |
我为什么做 (Why I did it)
They were the only module level functions having a “get_” prefix. All others do not.
它们是仅有的带有“ get_”前缀的模块级函数。 所有其他人都没有。
流程类的方法重命名 (Process class’ methods renamings)
什么改变了 (What changed)
All methods lost their “get_” and “set_” prefixes. A single method can now be used for both getting and setting (if a value is passed). Assuming p = psutil.Process():
所有方法都会丢失其“ get_”和“ set_”前缀。 现在可以使用一种方法进行获取和设置(如果传递了值)。 假设p = psutil.Process() :
Old name | 旧名 | Replacement | 替代 |
---|---|---|---|
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() |
…as for set_* methods:
…关于set_ *方法:
Old name | 旧名 | Replacement | 替代 |
---|---|---|---|
p.set_cpu_affinity() | p.set_cpu_affinity() | p.cpu_affinity(cpus) | p.cpu_affinity(cpus) |
p.set_ionice() | p.set_ionice() | p.ionice(ioclass, value=None) | p.ionice(ioclass,value = None) |
p.set_nice() | p.set_nice() | p.nice(value) | p.nice(值) |
p.set_rlimit() | p.set_rlimit() | p.rlimit(resource, limits=None) | p.rlimit(资源,限制=无) |
我为什么做 (Why I did it)
I wanted to be consistent with system-wide module level functions which have no “get_” prefix. After I got rid of “get_” prefixes removing also “set_” seemed natural and helped diminish the number of methods.
我想与没有“ get_”前缀的系统级模块级功能保持一致。 在摆脱“ get_”前缀之后,删除“ set_”似乎也很自然,这有助于减少方法的数量。
流程属性现在是方法 (Process properties are now methods)
什么改变了 (What changed)
Assuming p = psutil.Process():
假设p = psutil.Process() :
Old name | 旧名 | Replacement | 替代 |
---|---|---|---|
p.cmdline | cm | p.cmdline() | p.cmdline() |
p.create_time | p.create_time | p.create_time() | p.create_time() |
p.exe | 可执行文件 | p.exe() | p.exe() |
p.gids | 儿童 | p.gids() | p.gids() |
p.name | 名称 | p.name() | p.name() |
p.parent | 父母 | p.parent() | p.parent() |
p.ppid | ppid | p.ppid() | p.ppid() |
p.status | 状态 | p.status() | p.status() |
p.uids | 乌贼 | p.uids() | p.uids() |
p.username | p。用户名 | p.username() | p.username() |
我为什么做 (Why I did it)
Different reasons:
不同的原因:
- Having a mixed API which uses both properties and methods for no particular reason is confusing and messy as you don’t know whether to use “()” or not (see here).
- It is usually expected from a property to not perform many computations internally whereas psutil actually invokes a function every time it is accessed. This has two drawbacks:
- you may get an exception just by accessing the property (e.g. “p.name” may raise NoSuchProcess or AccessDenied)
- you may erroneously think properties are cached but this is true only for name, exe, and create_time.
- 混合使用没有特定原因的属性和方法的API会造成混乱和混乱,因为您不知道是否使用“()”(请参见此处 )。
- 通常希望从属性中内部不执行许多计算,而psutil实际上每次访问函数时都会调用一个函数。 这有两个缺点:
- 您可能仅通过访问属性而获得异常(例如,“ p.name”可能会引发NoSuchProcess或AccessDenied )
- 您可能会错误地认为属性已缓存,但这仅适用于name,exe和create_time。
CPU百分比间隔 (CPU percent intervals)
什么改变了 (What changed)
The timeout parameter of cpu_percent* functions now defaults to 0.0 instead of 0.1. The functions affected are:
现在, cpu_percent *函数的timeout参数默认为0.0,而不是0.1。 受影响的功能是:
psutil.cpu_percent()
psutil.cpu_percent()
psutil.cpu_times_percent()
psutil.cpu_times_percent()
为什么我改变了 (Why I changed it)
I originally set 0.1 as the default timeout because in order to get a meaningful percent value you need to wait some time.Having an API which “sleeps” by default is risky though, because it’s easy to forget it does so. That is particularly problematic when calling cpu_percent() for all processes: it’s very easy to forget about specifying timeout=0 resulting in dramatic slowdowns which are hard to spot. For example, this code snippet might take different seconds to complete depending on the number of active processes:
我最初将0.1设置为默认超时,因为要获得有意义的百分比值,您需要等待一段时间。但是具有默认情况下“Hibernate”的API很有风险,因为很容易忘记这样做。 当为所有进程调用cpu_percent()时,这尤其成问题:忘记指定timeout = 0会很容易忘记,这会导致难以发现的急剧下降。 例如,根据活动进程的数量,此代码段可能需要花费不同的时间才能完成:
迁移策略 (Migration strategy)
Except for Process properties (name, exe, cmdline, etc.) all the old APIs are still available as aliases pointing to the newer names and raising DeprecationWarning. psutil will be very clear on what you should use instead of the deprecated API as long you start the interpreter with the “-Wd” option. This will enable deprecation warnings which were silenced in Python 2.7 (IMHO, from a developer standpoint this was a bad decision).
除Process属性(名称,exe,cmdline等)外,所有旧API仍可用作别名,指向较新的名称并引发DeprecationWarning 。 只要您使用“ -Wd”选项启动解释器,psutil将会非常清楚应使用什么而不是不推荐使用的API。 这将启用弃用警告,该警告在Python 2.7中已被静音 (恕我直言,从开发人员的角度来看,这是一个错误的决定)。
Python 2.7.3 (default, Sep 26 2013, 20:03:06)
Python 2.7.3 (default, Sep 26 2013, 20:03:06)
[GCC 4.6.3] on linux2
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
Type "help", "copyright", "credits" or "license" for more information.
>>> import psutil
>>> import psutil
>>> psutil.get_pid_list()
>>> psutil.get_pid_list()
__main__:1: DeprecationWarning: psutil.get_pid_list is deprecated; use psutil.pids() instead
__main__:1: DeprecationWarning: psutil.get_pid_list is deprecated; use psutil.pids() instead
[1, 2, 3, 6, 7, 13, ...]
[1, 2, 3, 6, 7, 13, ...]
>>>
>>>
>>>
>>>
>>> p = psutil.Process()
>>> p = psutil.Process()
>>> p.get_cpu_times()
>>> p.get_cpu_times()
__main__:1: DeprecationWarning: get_cpu_times() is deprecated; use cpu_times() instead
__main__:1: DeprecationWarning: get_cpu_times() is deprecated; use cpu_times() instead
pcputimes(user=0.08, system=0.03)
pcputimes(user=0.08, system=0.03)
>>>
>>>
If you have a solid test suite you can run tests and fix the warnings one by one.
如果您有可靠的测试套件,则可以逐个运行测试并修复警告。
As for the the Process properties which were turned into methods it’s more difficult because whereas psutil 1.2.1 returns the actual value, psutil 2.0.0 will return the bound method:
至于变成了方法的Process属性,则更加困难,因为psutil 1.2.1返回实际值,而psutil 2.0.0将返回绑定方法:
What I would recommend if you want to drop support with 1.2.1 is to grep for “.name”, “.exe” etc. and just replace them with “.exe()” and “.name()” one by one.If on the other hand you want to write a code which works with both versions I see two possibilities:
如果您要放弃对1.2.1的支持,我建议您使用grep表示“ .name”,“。exe”等,然后将它们分别替换为“ .exe()”和“ .name()” 。另一方面,如果您想编写适用于两个版本的代码,则有两种可能:
#1 check version info, like this:
#1检查版本信息,如下所示:
>>> p = psutil.Process()
>>> p = psutil.Process()
>>> name = p.name() if PSUTIL2 else p.name
>>> name = p.name() if PSUTIL2 else p.name
>>> exe = p.exe() if PSUTIL2 else p.exe
>>> exe = p.exe() if PSUTIL2 else p.exe
#2 get rid of all “.name”, “.exe” occurrences you have in your code and use as_dict() instead:
#2消除代码中出现的所有“ .name”,“。exe”,并使用as_dict()代替:
2.0.0中引入的新功能 (New features introduced in 2.0.0)
Ok, enough with the bad news. =) psutil 2.0.0 is not only about code breakage. I also had the chance to integrate a bunch of interesting features.
好,有了坏消息就好了。 =)psutil 2.0.0不仅与代码损坏有关。 我也有机会集成了许多有趣的功能。
- issue 427: you’re now able to distinguish between the number of logical and physical CPUs:
- 问题427 :现在,您可以区分逻辑和物理CPU的数量:
4
4
>>> psutil.cpu_count(logical=False) # physical cores only
>>> psutil.cpu_count(logical=False) # physical cores only
2
2
- issue 452: process classes are now hashable and can be checked for equality. That means you can use Process objects with sets (finally!).
- issue 447: psutil.wait_procs() “timeout” parameter is now optional
- issue 461: functions returning namedtuples are now pickle-able
- issue 459: a Makefile is now available to automatize repetitive tasks such as build, install, running tests etc. There’s also a make.bat for Windows.
- introduced unittest2 module as a requirement for running tests
- 问题452 :进程类现在可以进行哈希处理,并且可以检查其是否相等。 这意味着您可以将Process对象与集合一起使用(最终!)。
- 问题447 : psutil.wait_procs() “超时”参数现在是可选的
- 问题461 :返回命名元组的函数现在可以进行腌制
- 问题459 :现在可以使用Makefile来自动执行重复性任务,例如构建,安装,运行测试等。还有用于Windows的make.bat 。
- 引入unittest2模块作为运行测试的要求
翻译自: https://www.pybloggers.com/2014/01/psutil-2-0-porting/
usb 2.2.0移植