2013-04-01 36 views
11

Tôi đang học cách sử dụng Qt với PyQt, và tôi có một QTabelView với một StandardItemModel Tôi đã điền mô hình thành công và kết nối tín hiệu itemChanged với một khe. Tôi muốn l'muốn giỡn mặt với bất cứ điều gì đối tượng được trả về trong IPython, vì vậy hiện tại tôi có các dòng:Tôi có thể lấy một đối tượng python từ địa chỉ bộ nhớ của nó không?

def itemChangedSlot(epw, item): 
    new_data = item.data() 
    print new_data 
    print item 

mà in

<PyQt4.QtGui.QStandardItem object at 0x07C5F930> 
<PyQt4.QtCore.QVariant object at 0x07D331F0> 

Trong phiên IPython là nó có thể để có được đối tượng sử dụng địa chỉ bộ nhớ này? Tôi không thấy bất cứ điều gì trên Google, có lẽ tôi không có thuật ngữ của tôi đúng không?

+1

Đối tượng 'new_data' mà bạn đang in là đối tượng. Chỉ cần trả lại hoặc lưu trữ thay vì in nó. – BrenBarn

+0

Nó không phải là _impossible_ để làm điều đó, nhưng nó không phải dễ dàng, và nó không phải là tài liệu để làm việc trong mọi trường hợp, và nó thường là một ý tưởng rất xấu. Nếu bạn đang thử nghiệm với cách CPython hoạt động dưới bìa, hoặc gỡ lỗi bộ thu gom rác, hoặc một cái gì đó như thế, nó có thể đáng làm, nhưng nếu không, bạn đang sủa cây sai, và câu trả lời của Raymond Hetting là những gì bạn muốn . – abarnert

Trả lời

8

Bạn gần như chắc chắn đặt câu hỏi sai và câu trả lời của Raymond Hettinger gần như chắc chắn là những gì bạn thực sự muốn.

Một cái gì đó như thế này có thể hữu ích khi cố gắng đào sâu vào nội bộ của trình thông dịch CPython cho mục đích học tập hoặc kiểm tra nó cho lỗ hổng bảo mật hoặc một cái gì đó ... Nhưng thậm chí sau đó, bạn có thể tốt hơn việc nhúng trình thông dịch Python vào một chương trình và viết các hàm hiển thị bất cứ thứ gì bạn muốn vào trình thông dịch Python, hoặc ít nhất là viết một mô-đun mở rộng C cho phép bạn thao tác các đối tượng CPython.

Nhưng, trên cơ hội ra rằng bạn thực sự cần phải làm điều này ...

Thứ nhất, không có cách nào đáng tin cậy để thậm chí có được địa chỉ từ repr. Hầu hết các đối tượng có đại diện hữu ích eval sẽ cho bạn thay thế. Ví dụ: repr của ('1', 1)"('1', 1)", không phải <tuple at 0x10ed51908>. Ngoài ra, ngay cả đối với các đối tượng không có biểu diễn hữu ích, việc trả về <TYPE at ADDR> chỉ là một quy ước không được nhắc đến mà nhiều loại theo (và mặc định cho các lớp do người dùng định nghĩa), chứ không phải thứ bạn có thể dựa vào.

Tuy nhiên, kể từ khi bạn có lẽ chỉ quan tâm đến CPython, bạn có thể dựa vào id:

CPython chi tiết thực hiện: Đây là địa chỉ của đối tượng trong bộ nhớ.

(Tất nhiên nếu bạn có đối tượng để gọi id (hoặc repr), bạn không cần phải dereference nó thông qua con trỏ, và nếu bạn không có đối tượng, nó có thể được thu gom rác thải để không có gì để dereference, nhưng có lẽ bạn vẫn còn có nó và chỉ không thể nhớ nơi bạn đặt nó ...)

Tiếp theo, bạn làm gì với địa chỉ này? Vâng, Python không phơi bày bất kỳ chức năng nào để làm điều ngược lại của id. Nhưng Python C API cũng được ghi lại và — nếu Python của bạn được xây dựng xung quanh một thư viện được chia sẻ, C API có thể được truy cập thông qua ctypes, chỉ bằng cách tải nó lên. Trên thực tế, ctypes cung cấp một biến đặc biệt tự động tải thư viện được chia sẻ phù hợp để gọi API C trên, ctypes.pythonapi.

Trong phiên bản cũ của ctypes, bạn có thể phải tìm và tải nó một cách rõ ràng, như pydll = ctypes.cdll.LoadLibrary('/usr/lib/libpython2.5.so') (Đây là cho linux với Python 2.5 được cài Tất nhiên sẽ dễ dàng hơn khi gặp trình thông dịch Python làm việc này hơn là làm bất cứ điều gì hữu ích, nhưng không thể làm bất cứ điều gì hữu ích, và bạn có thể thử nghiệm thú vị với nó.

7

Bạn cần giữ tham chiếu đến một đối tượng (ví dụ: chỉ định nó cho một biến hoặc lưu trữ nó trong danh sách).

Không có hỗ trợ ngôn ngữ để chuyển từ một địa chỉ đối tượng trực tiếp đến một đối tượng (ví dụ: pointer dereferencing).

Các vấn đề liên quan