Tôi đã viết một lớp đơn giản sau đây như một cách hiệu quả để mô phỏng một con trỏ trong python:
class Parameter:
"""Syntactic sugar for getter/setter pair
Usage:
p = Parameter(getter, setter)
Set parameter value:
p(value)
p.val = value
p.set(value)
Retrieve parameter value:
p()
p.val
p.get()
"""
def __init__(self, getter, setter):
"""Create parameter
Required positional parameters:
getter: called with no arguments, retrieves the parameter value.
setter: called with value, sets the parameter.
"""
self._get = getter
self._set = setter
def __call__(self, val=None):
if val is not None:
self._set(val)
return self._get()
def get(self):
return self._get()
def set(self, val):
self._set(val)
@property
def val(self):
return self._get()
@val.setter
def val(self, val):
self._set(val)
Đây là một ví dụ về cách sử dụng (từ trang sổ ghi chép jupyter):
l1 = list(range(10))
def l1_5_getter(lst=l1, number=5):
return lst[number]
def l1_5_setter(val, lst=l1, number=5):
lst[number] = val
[
l1_5_getter(),
l1_5_setter(12),
l1,
l1_5_getter()
]
Out = [5, None, [0, 1, 2, 3, 4, 12, 6, 7, 8, 9], 12]
p = Parameter(l1_5_getter, l1_5_setter)
print([
p(),
p.get(),
p.val,
p(13),
p(),
p.set(14),
p.get()
])
p.val = 15
print(p.val, l1)
[12, 12, 12, 13, 13, None, 14]
15 [0, 1, 2, 3, 4, 15, 6, 7, 8, 9]
Tất nhiên, cũng dễ dàng thực hiện điều này đối với các mục hoặc thuộc tính dict của một đối tượng. Thậm chí còn có một cách để thực hiện những gì OP yêu cầu, bằng cách sử dụng các hình cầu ():
def setter(val, dict=globals(), key='a'):
dict[key] = val
def getter(dict=globals(), key='a'):
return dict[key]
pa = Parameter(getter, setter)
pa(2)
print(a)
pa(3)
print(a)
Điều này sẽ in ra 2, tiếp theo là 3.
Lộn xộn với không gian tên toàn cầu theo cách này rõ ràng là một ý tưởng khủng khiếp, nhưng nó cho thấy rằng có thể (nếu không thể thực hiện được) để thực hiện những gì OP yêu cầu.
Tất nhiên, ví dụ này khá vô nghĩa. Nhưng tôi nhận thấy lớp này hữu ích trong ứng dụng mà tôi đã phát triển nó: một mô hình toán học có hành vi được điều chỉnh bởi nhiều tham số toán học do người dùng thiết lập, thuộc nhiều loại khác nhau (mà vì chúng phụ thuộc vào các đối số dòng lệnh, không được biết đến tại thời điểm biên dịch). Và một khi quyền truy cập vào một thứ gì đó đã được gói gọn trong một đối tượng Tham số, tất cả các đối tượng đó có thể được thao tác theo một cách thống nhất.
Mặc dù nó trông không giống một con trỏ C hoặc C ++, nhưng điều này đang giải quyết một vấn đề mà tôi sẽ giải quyết với con trỏ nếu tôi viết bằng C ++.