程序员文章、书籍推荐和程序员创业信息与资源分享平台

网站首页 > 技术文章 正文

鲜为人知的 Python 函数(python函数代码大全)

hfteth 2025-05-03 14:21:44 技术文章 30 ℃

Python 有很多很酷的功能,例如一等函数、lambda、生成器、推导式等。关于

这个主题的文章很多。但是,Python 中的一些功能通常不是那么常用。

1. 限制 CPU 和内存使用

我 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 resource
import signal
import 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 task
print('Starting:', time.ctime())
for i in range(300000):
    for j in range(220000):
        _ = i * j# Will not be able to execute this!
print('Exiting :', time.ctime())

在这里,对于 CPU 限制,我们首先获得该特定资源 (RLIMIT_CPU) 的软限制和硬限制,然后将其设置为 10 秒,同时保持硬限制与以前相同。最后,我们注册信号,如果超过 CPU 时间,则会导致系统退出。

执行上述代码段将生成以下输出:

Soft limit starts as  : 922304775807
Soft limit changed to : 10
Starting: Sun Apr  5 20:27:09 2020
EXPIRED : Sun Apr  5 20:27:19 2020
(time ran out)

至于内存,我们同样可以使用 resource RLIMIT_AS 检索软限制和硬限制,并使用带有所需参数的 setrlimit 进行设置。

# To limit memory usage
def set_max_memory(size):    # size (in bytes)
    soft, hard = resource.getrlimit(resource.RLIMIT_AS)
    resource.setrlimit(resource.RLIMIT_AS, (size, hard))

2. 控制可以导入的内容和不可以导入的内容

在 Python 中,using from import * 将导入该模块的所有公共对象。例如:

# person.pyname = "Sarah"
age = 26def foo():
    return name# __all__ = ["name", "age"]   <-- commented out

当我们使用 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>>> foo()
NameError: name 'foo' is not defined

因此,__all__ 让我们知道模块的 “public” 功能。但是,应该注意的是,不带 * 的导入完全不受影响。

>>> from person import foo
>>> foo()
'Sarah'

3. 仅包含 Keyword Arguments 的函数

我们可以有意识地创建只接受 keyword 参数的函数,以便在使用此类函数时更加清晰:

def person(*, name, age):
   print(name, age) >>> person("Sarah", 26)
TypeError: person() takes 0 positional arguments>>> person(name="Sarah", age=26)
Sarah 26

正如我们所看到的,这可以通过在关键字参数之前放置单个 * 参数来轻松完成。如果我们将位置参数放在 * 参数之前,显然会有位置参数。

4. 使用__slots__节省内存

在 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'

Tags:

最近发表
标签列表