摘要:import resourcec_soft, c_hard = resource.getrlimit(resource.RLIMIT_CPU)print('soft limit %d secs, hard limit %d secs' % (c_soft, c
Python 有很多很酷的功能,例如一等函数、lambda、生成器、推导式等。关于这个主题的文章很多。但是,Python 中的一些功能通常不是那么常用。
我 Python 程序使用的 CPU、内存等资源可以使用资源库进行控制。
要获取进程可以使用的处理器时间(以秒为单位),可以使用 resource.getrlimit 方法。它返回资源的当前软限制和硬限制。
import resourcec_soft, c_hard = resource.getrlimit(resource.RLIMIT_CPU)print('soft limit %d secs, hard limit %d secs' % (c_soft, c_hard))>>>soft limit 922304775807 secs, hard limit 922304775807 secs每个资源都由一对限制控制:软限制和硬限制。软限制是当前限制,并且可能会随着时间的推移由进程降低或提高。软限制永远不能超过硬限制。硬限制可以降低到大于软限制的任何值,但不能提高。
以下代码片段通过将软限制设置为 10 秒来限制程序的 CPU 使用率。因此,该进程的处理器时间不会超过 10 秒:
import resourceimport signalimport timedef time_expired(n, stack): print('EXPIRED :', time.ctime) raise SystemExit('(time ran out)')def set_cpu_runtime: # Install the signal handler and set a resource limit soft, hard = resource.getrlimit(resource.RLIMIT_CPU) print('Soft limit starts as :', soft) resource.setrlimit(resource.RLIMIT_CPU, (10, hard)) soft, hard = resource.getrlimit(resource.RLIMIT_CPU) print('Soft limit changed to :', soft) signal.signal(signal.SIGXCPU, time_expired)set_cpu_runtime# Performing a CPU intensive taskprint('Starting:', time.ctime)for i in range: for j in range: _ = i * j# Will not be able to execute this!print('Exiting :', time.ctime)在这里,对于 CPU 限制,我们首先获得该特定资源 (RLIMIT_CPU) 的软限制和硬限制,然后将其设置为 10 秒,同时保持硬限制与以前相同。最后,我们注册信号,如果超过 CPU 时间,则会导致系统退出。
执行上述代码段将生成以下输出:
Soft limit starts as : 922304775807Soft limit changed to : 10Starting: Sun Apr 5 20:27:09 2020EXPIRED : Sun Apr 5 20:27:19 2020(time ran out)至于内存,我们同样可以使用 resource RLIMIT_AS 检索软限制和硬限制,并使用带有所需参数的 setrlimit 进行设置。
# To limit memory usagedef set_max_memory(size): # size (in bytes) soft, hard = resource.getrlimit(resource.RLIMIT_AS) resource.setrlimit(resource.RLIMIT_AS, (size, hard))在 Python 中,using from import * 将导入该模块的所有公共对象。例如:
# person.pyname = "Sarah"age = 26def foo: return name# __all__ = ["name", "age"]当我们使用 from person import * 语句导入 person 模块时,它将在后台导入模块的 __all__ 变量中存在的所有符号。
__all__ 变量是一个字符串列表,用于定义将导出模块中的哪些元件。默认情况下,它将以字符串形式包含所有公共对象,因此我们可以访问 person 模块的任何成员,如下所示:
>>> from person import *>>> print(name, age)Sarah, 26>>> foo'Sarah'但是,我们可以通过覆盖 __all__ 的值来限制可以导入的内容。在上面的例子中,如果我们取消 __all__ = [“name”, “age”] 语句的注释并尝试访问 foo 方法,它将向我们抛出一个错误:
>>> from person import *>>> print(name, age)Sarah, 26>>> fooNameError: name 'foo' is not defined因此,__all__ 让我们知道模块的 “public” 功能。但是,应该注意的是,不带 * 的导入完全不受影响。
>>> from person import foo>>> foo'Sarah'我们可以有意识地创建只接受 keyword 参数的函数,以便在使用此类函数时更加清晰:
def person(*, name, age): print(name, age) >>> person("Sarah", 26)TypeError: person takes 0 positional arguments>>> person(name="Sarah", age=26)Sarah 26正如我们所看到的,这可以通过在关键字参数之前放置单个 * 参数来轻松完成。如果我们将位置参数放在 * 参数之前,显然会有位置参数。
在 Python 中,每个类都可以具有实例属性。如果我们编写的程序正在创建某个类的大量实例,我们可能会注意到我们的程序将需要大量内存。
这是因为,默认情况下 Python 使用字典来存储对象的实例属性,这使得它很快,但内存效率不高(通常不是问题)。但是,如果它对我们的程序造成问题,我们可能会尝试使用 __slots__。
插槽提供了一种特殊的机制来减小对象的大小。
class Person: __slots__ = ["name", "age", "email"] def __init__(self, name, age, email): self.name = name self.age = age self.email = email在上面的代码片段中,我们定义了__slots__属性,它指示 Python 对属性使用小的固定大小的数组而不是字典,这大大减少了每个实例所需的内存。
使用 __slots__ 也有一些缺点。 我们不能动态声明任何新属性,因此仅限于使用 __slots__ 上的 属性。
>>> p = Person('Sarah', 26, 'akp345@gmail.com')>>> p.new = 'Not Possible'AttributeError: 'Person' object has no attribute 'new'来源:自由坦荡的湖泊AI