python通配符使用技巧大全_Python小技巧(二)

5、用__slots__节省内存

如果你曾经编写过一个程序,该程序创建了某个类的大量实例,那么你可能已经注意到你的程序突然就需要大量内存。那是因为 Python 使用字典来表示类实例的属性,这能使其速度变快,但内存不是很高效。通常这不是个问题,但是,如果你的程序遇到了问题,你可以尝试使用__slots__ :

class Person:

__slots__ = ["first_name", "last_name", "phone"]

def __init__(self, first_name, last_name, phone):

self.first_name = first_name

self.last_name = last_name

self.phone = phone

这里发生的是,当我们定义__slots__属性时,Python 使用固定大小的小型数组,而不是字典,这大大减少了每个实例所需的内存。使用__slots__还有一些缺点——我们无法声明任何新的属性,并且只能使用在__slots__中的属性。同样,带有__slots__的类不能使用多重继承。

6、限制CPU和内存使用量

如果不是想优化程序内存或 CPU 使用率,而是想直接将其限制为某个固定数字,那么 Python 也有一个库能做到:

import signal

import resource

import os

# To Limit CPU time

def time_exceeded(signo, frame):

print("CPU exceeded...")

raise SystemExit(1)

def set_max_runtime(seconds):

# Install the signal handler and set a resource limit

soft, hard = resource.getrlimit(resource.RLIMIT_CPU)

resource.setrlimit(resource.RLIMIT_CPU, (seconds, hard))

signal.signal(signal.SIGXCPU, time_exceeded)

# To limit memory usage

def set_max_memory(size):

soft, hard = resource.getrlimit(resource.RLIMIT_AS)

resource.setrlimit(resource.RLIMIT_AS, (size, hard))

在这里,我们可以看到两个选项,可设置最大 CPU 运行时间和内存使用上限。对于 CPU 限制,我们首先获取该特定资源(RLIMIT_CPU)的软限制和硬限制,然后通过参数指定的秒数和先前获取的硬限制来设置它。最后,如果超过 CPU 时间,我们将注册令系统退出的信号。至于内存,我们再次获取软限制和硬限制,并使用带有 size 参数的setrlimit和获取的硬限制对其进行设置。

8、控制可以import的内容

某些语言具有非常明显的用于导出成员(变量、方法、接口)的机制,例如Golang,它仅导出以大写字母开头的成员。另一方面,在 Python 中,所有内容都会被导出,除非我们使用__all__ :

def foo():

pass

def bar():

pass

__all__ = ["bar"]

使用上面的代码段,我们可以限制from some_module import *在使用时可以导入的内容。对于以上示例,通配导入时只会导入 bar。此外,我们可以将__all__ 设为空,令其无法导出任何东西,并且在使用通配符方式从此模块中导入时,将引发 AttributeError。

9、比较运算符的简便方法

为一个类实现所有比较运算符可能会很烦人,因为有很多的比较运算符——__lt__、__le__、__gt__ 或__ge__。但是,如果有更简单的方法呢?functools.total_ordering可救场:

from functools import total_ordering

@total_ordering

class Number:

def __init__(self, value):

self.value = value

def __lt__(self, other):

return self.value 

def __eq__(self, other):

return self.value == other.value

print(Number(20) > Number(3))

print(Number(1) 

print(Number(15) >= Number(15))

print(Number(10) <= Number(2))

这到底如何起作用的?total_ordering 装饰器用于简化为我们的类实例实现排序的过程。只需要定义__lt__ 和__eq__,这是最低的要求,装饰器将映射剩余的操作——它为我们填补了空白。

(译注:原作者的文章分为两篇,为了方便读者们阅读,我特将它们整合在一起,以下便是第二篇的内容。)

10、使用slice函数命名切片

使用大量硬编码的索引值会很快搞乱维护性和可读性。一种做法是对所有索引值使用常量,但是我们可以做得更好:

# ID   First Name   Last Name

line_record = "2        John         Smith"

ID = slice(0, 8)

FIRST_NAME = slice(9, 21)

LAST_NAME = slice(22, 27)

name = f"{line_record[FIRST_NAME].strip()} {line_record[LAST_NAME].strip()}"

# name == "John Smith"

在此例中,我们可以避免神秘的索引,方法是先使用 slice 函数命名它们,然后再使用它们。你还可以通过 .start、.stop和 .stop 属性,来了解 slice 对象的更多信息。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值