Python del 标记安全实例变量为垃圾收集
我有一个敏感数据字段,我希望它在内存中的生命周期尽可能短。根据这篇文章这里,我有以下的实现:
class UserData:
def __init__(data):
self.user_data = data #sensitive data
def get_user_data(self):
return UserData.decrypt(self.user_data)
@staticmethod
def decrypt(data):
...
根据这篇文章这里,看起来我能做的最好方法就是使用del命令,让这个字符串可以被垃圾回收器回收。我有以下的实现:
class UserData:
def __init__(data):
self.user_data = data #sensitive data
self._decrypted_user_data = None
@contextmanager
def get_user_data(self):
self._decrypted_user_data = UserData.decrypt(self.user_data)
yield
del self._decrypted_user_data
@staticmethod
def decrypt(data):
...
我有两个问题:
对实例变量使用del命令是否会让这个变量可以被垃圾回收器回收(也就是说,这个实例变量的引用计数是否变为0)。我之所以问这个,是因为我知道dict会返回属性。如果不是,有没有办法只标记这个实例准备好被垃圾回收,而不是整个对象?
这样做比把self._decrypted_user_data设为None更安全吗?
1 个回答
3
del
只是把一个对象标记为垃圾,不会立即删除它。
在Python中,字符串是不可变的。即使你用 del
删除了一个字符串,它在内存中仍然存在,只是无法再访问了。可以考虑使用另一种可以被覆盖的类型:
bytearray([source[, encoding[, errors]]])
返回一个新的字节数组。
bytearray
类型是一种可变的整数序列,范围在 0 到 255 之间。它有大多数可变序列的常用方法,具体可以参考可变序列类型,同时也有大部分字节类型的方法,详情见字节和字节数组方法。
https://docs.python.org/3.1/library/functions.html#bytearray
为了存储密码,可以将其作为 bytearray
进行读写,也就是一串数字。要删除密码,可以覆盖 bytearray
中的元素,然后用 del
删除引用。即使这个对象再次出现,它也会变成一堆无意义的字符。