![](/img/trans.png)
[英]How can I cleanly assign class attributes as an instance of that class in Python?
[英]How can I retrieve the instance of a class from a value of one of its attributes?
我想(優雅地)序列化不同類實例中屬性之間的連接。 例如:
class AttrClass(object):
def __init__(self, value=None):
self.value = value
class ObjClass(object):
def __init__(self, name, value=None):
self.name = name
self.foo = AttrClass(value=value)
out_obj = ObjClass('out', value='bar')
in_obj = ObjClass('in', value=out_obj.foo)
in_obj.foo
# Result: <AttrClass object at 0x000001B086B0A470>
在這種情況下,盡管我也想找到out_obj
類的out_obj
實例和屬性名稱foo
。 如果將self
和'foo'
傳遞到AttrClass初始化中,則可以完成此操作,但這對於用戶每次使用該類作為值創建新屬性時繼續輸入它都是令人討厭的。
有沒有一種方法可以從一個值追溯到屬性名稱,即屬性的值以及該屬性所屬的類實例?
另外,有沒有一種方法可以在實例化時自動將類實例和屬性名稱添加到類中? 例如:
class AttrClass(object):
def __init__(self, value=None):
self.value = value
self.host_class = self.do_magic_class_thing()
self.host_attr = self.do_magic_attr_thing()
out_obj = ObjClass('out', value='bar')
in_obj = ObjClass('in', value=out_obj.foo)
in_obj.foo.host_class.name
# Result: 'out'
您不能,至少不能優雅地-可以用很多inspect
魔術來做到這一點,但是它很快就會變得丑陋。 這個“問題”幾乎存在於所有依賴於解釋器/ VM的語言中,通過引用計數進行內存管理的語言-如果對象的子對象要存儲對其父對象的引用,您將得到一個循環引用計數,該計數無法快速解決,並且可以混亂不堪,所以語言設計人員通常選擇不這樣做,而由開發人員自行處理。
因此,在您的特定情況下,由於您包裝了AttrClass
實例的值,因此您可以使這些實例對其父對象的引用如下:
class AttrClass(object):
def __init__(self, parent, value=None):
self.parent = parent
self.value = value
class ObjClass(object):
def __init__(self, name, value=None):
self.name = name
self.foo = AttrClass(self, value=value)
out_obj = ObjClass('out', value='bar')
in_obj = ObjClass('in', value=out_obj.foo)
assert in_obj.foo.value.parent is out_obj # passes
print(in_obj.foo.value.parent.name) # out
此外,是否有任何特殊原因需要編寫自己的串行器/解串器? 有很多這樣的東西,我敢肯定至少有一些適合您的用例。 我全力推薦MessagePack 。
妳去 該代碼的保證為零,因為它依賴於解釋器實現中的Python堆棧框架支持。
import inspect, re
class AttrClass(object):
def __init__(self, value=None):
self.value = value
stack = inspect.stack() # get the stack
goback = stack[2] # go down the stack 2 step
entry_point = goback[4] # get the code context to get "object name" [4] is from stack format
name = re.findall("ObjClass\(.*value=([^)]*)\)", entry_point[0]) # magic hack to get "out_obj"
if len(name) > 0:
obj_name = name[0].split('.')[0] # get the object's name.
argvalues = inspect.getargvalues(goback.frame)[3] # [3] to get `locals` from tuple returned.
if obj_name in argvalues:
setattr(self, 'host_class', argvalues[obj_name]) # iject the attribute
else: #Sorry can't find it
setattr(self, 'host_class', None)
class ObjClass(object):
def __init__(self, name, value=None):
self.name = name
self.foo = AttrClass(value=value)
out_obj = ObjClass('out', value='bar')
in_obj = ObjClass('in', value=out_obj.foo)
print(in_obj.foo.host_class.name)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.