Bạn có thể coi trọng một id biến được truy xuất từ hàm id
bằng Python không? Ví dụ:Có thể dereference variable id's?
dereference(id(a)) == a
Tôi muốn biết từ quan điểm học tập; Tôi hiểu rằng có nhiều phương pháp thực tế hơn.
Bạn có thể coi trọng một id biến được truy xuất từ hàm id
bằng Python không? Ví dụ:Có thể dereference variable id's?
dereference(id(a)) == a
Tôi muốn biết từ quan điểm học tập; Tôi hiểu rằng có nhiều phương pháp thực tế hơn.
Dưới đây là một chức năng hữu ích dựa trên một comment do "Tiran" trong các cuộc thảo luận Hophat Abc referenced mà sẽ làm việc trong cả hai Python 2 và 3:
import _ctypes
def di(obj_id):
""" Inverse of id() function. """
return _ctypes.PyObj_FromPtr(obj_id)
if __name__ == '__main__':
a = 42
b = 'answer'
print(di(id(a))) # -> 42
print(di(id(b))) # -> answer
Không dễ dàng.
Bạn có thể kiểm tra lại danh sách gc.get_objects()
, kiểm tra từng đối tượng nếu nó có cùng số id()
nhưng điều đó không thực tế lắm.
Chức năng id()
là không được dự định sẽ không thể chấp nhận được; thực tế là nó được dựa trên địa chỉ bộ nhớ là một chi tiết thực hiện CPython, rằng việc triển khai Python khác không tuân theo.
Given: 'a = 1',' b = a', 'c = a' ... a, b, c tất cả đều có cùng một' id() '. –
Chắc chắn, họ có cùng một id. Điều đó có liên quan gì với câu hỏi OP? –
Chỉ cần lưu ý rằng tham chiếu của một biến là tất cả cùng một đối tượng. –
Có một số cách và nó không phải là khó khăn để làm:
Trong O (n)
In [1]: def deref(id_):
....: f = {id(x):x for x in gc.get_objects()}
....: return f[id_]
In [2]: foo = [1,2,3]
In [3]: bar = id(foo)
In [4]: deref(bar)
Out[4]: [1, 2, 3]
Một cách nhanh hơn trên trung bình, từ các ý kiến (nhờ @Martijn Pieters):
def deref_fast(id_):
return next(ob for ob in gc.get_objects() if id(ob) == id_)
Giải pháp nhanh nhất là trong câu trả lời từ @martineau, nhưng không yêu cầu phơi bày nội bộ python. Các giải pháp trên sử dụng cấu trúc python chuẩn.
Bây giờ bạn đã tạo một tham chiếu đến * mọi giá trị trong bộ nhớ * đảm bảo rằng chúng sẽ không bị thu gom rác. Bạn thực sự muốn sử dụng [module 'weakref'] (http://docs.python.org/2/library/weakref.html#weakref.WeakValueDictionary) để thay thế. –
OP được hỏi từ quan điểm học tập, không phải là quan điểm thực tế. – munk
Nhưng OP sẽ không phải là người duy nhất xem xét điều này; ý tưởng tạo ra một ánh xạ của id-to-object là tốt đẹp, nhưng nó có những hậu quả nhất định mà bạn cần phải biết. –
Module di có một hàm C cho phép bạn làm điều này cung cấp các đối tượng đã không được thu gom rác thải: http://www.friday.com/bbum/2007/08/24/python-di/
+1 Loại tuyệt vời trong sự đơn giản của nó. – martineau
Dưới đây là thêm một câu trả lời được chuyển thể từ chưa comment khác, một trong những điều này bằng cách "Peter Fein", trong phần thảo luận Hophat Abc tham chiếu trong câu trả lời của riêng mình cho câu hỏi của chính mình .
Mặc dù không phải là câu trả lời chung nhưng có thể vẫn hữu ích trong trường hợp bạn biết điều gì đó về lớp của đối tượng có id bạn muốn tra cứu - trái ngược với id là mọi thứ. Ý tưởng cơ bản là tạo một lớp theo dõi các cá thể và các lớp con của chính nó. Tôi cảm thấy đây có thể là một kỹ thuật đáng giá ngay cả với giới hạn đó.
import weakref
class InstanceTracker(object):
""" base class that tracks instances of its subclasses using weakreferences """
class __metaclass__(type):
""" Metaclass for InstanceTracker """
def __new__(cls, name, bases, dic):
cls = super(cls, cls).__new__(cls, name, bases, dic)
cls.__instances__ = weakref.WeakValueDictionary()
return cls
def __init__(self, *args, **kwargs):
self.__instances__[id(self)]=self
super(InstanceTracker, self).__init__(*args, **kwargs)
@classmethod
def find_instance(cls, obj_id):
return cls.__instances__.get(obj_id, None)
if __name__ == '__main__':
class MyClass(InstanceTracker):
def __init__(self, name):
super(MyClass, self).__init__()
self.name = name
def __repr__(self):
return '{}({!r})'.format(self.__class__.__name__, self.name)
obj1 = MyClass('Bob')
obj2 = MyClass('Sue')
print MyClass.find_instance(id(obj1))
print MyClass.find_instance(id(obj2))
print MyClass.find_instance(42)
Output:
MyClass('Bob')
MyClass('Sue')
None
FWIW, IMHO đánh dấu đây là như một bản sao của một câu hỏi mà chấp nhận câu trả lời về cơ bản là "có thể bạn không muốn làm điều đó" không phải là hữu ích. – martineau
@martineau: cũng có những câu trả lời khác nữa :) –