[英]is using array with meaningful field name values not pythonic for a Python struct?
我已經看到了幾個有關如何在Python中實現類似C struct
問題。 通常人們會推薦一個namedtuple
但是問題是,它的字段不是可變的,而且我認為擁有不可變的結構沒有多大意義,因此,如果需要的話,建議使用dictionary
,我認為這是一個好方法,太冗長-您必須用引號將字段名括起來,而且速度必須非常慢-您必須搜索字段值。
我從來沒有看到對我來說似乎是自然的解決方案:
i = -1
i += 1
FIELD_A = i
i += 1
FIELD_B = i
i += 1
FIELD_C = i
structure = [ 0, "foo", "bar" ]
structure[FIELD_A] = 1
i
操作的原因是,它允許復制和粘貼,而不會兩次分配相同的值或浪費空間。 使用大寫字母的原因是使這些值突出顯示為“恆定”。
我是不是很天真,上面有什么問題,或者不是Pythonic?
使用字典的替代代碼:
structure = {}
structure["FIELD1"] = 0
structure["FIELD2"] = "foo"
structure["FIELD3"] = "bar
在我看來,更少的代碼行,並且更具可讀性,因為您不必懷疑i
發生了什么。 由於沒有方便的dict替代方法,因此我在MATLAB中實際使用了您的方法。
此外,如果您覺得可讀性更高,也沒有什么可以阻止您使用大寫字母。
我認為,以Python方式最接近C結構的類比是具有命名屬性的Python對象。
繁瑣的方式:
class mystruct:
def __init__(self):
self.FIELD1 = None
self.FIELD2 = None
self.FIELD3 = None
x = mystruct()
x.FIELD1 = 42
x.FIELD3 = "aap"
使用type
函數可以使匿名對象具有許多屬性:
y = type('', (), {'FIELD1': None, 'FIELD2':None})()
y.FIELD1 = 42
但這仍然很麻煩。 但這可以很容易地通過編寫返回一個將創建對象實例的函數的函數來概括。
# 'objmaker' takes a list of field names and returns a function
# which will create an instance of an object with those fields, their
# values initially set to None
objmaker = lambda *fields: type('', (), {field: None for field in fields})
# Now it's trivial to define new 'structs' - here we 'define' two
# types of 'structs'
mystruct_maker = objmaker('FIELD1', 'FIELD2', 'FIELD3')
yourstruct_maker = objmaker('x', 'y')
# And creating instances goes like this:
my_str1 = mystruct_maker()
my_str2 = mystruct_maker()
yr_str = yourstruct_maker()
yr_str.x = 42
my_str1.FIELD1 = yr_str.x
“它必須非常慢-您必須搜索字段值。” 如果您認為字典查找速度很慢,那么python會給您帶來一系列心臟病發作。 考慮
foo = 'somestring'
bar = bar
baz = someobj.variable
Python計算了'somestring'
的哈希值,因為它在創建所有字符串時都會執行此操作。 每次我們提到它們時,它在模塊的命名空間dict
看起來都是foo
和bar
。 訪問對象變量涉及在對象的dict
查找它們。
獲得類結構行為的幾種方法是定義類級變量或使用__slots__
定義對象的固定變量集。
class MyStruct(object):
FIELD1 = 0
FIELD2 = 'foo'
FIELD3 = 'bar'
print(MyStruct.FIELD2)
s = MyStruct()
s.FIELD2 = 'baz'
print(s.FIELD2)
class MySlots(object):
__slots__ = ['FIELD1', 'FIELD2', 'FIELD3']
def __init__(self, FIELD1=0, FIELD2='foo', FIELD3='bar'):
self.FIELD1 = FIELD1
self.FIELD2 = FIELD2
self.FIELD3 = FIELD3
s = MySlots()
print(s.FIELD2)
這些也許很令人愉快,但是它們並不比使用dict
快。
我很感謝其他所有答案,但他們並未真正回答這個問題。 提出的問題是“我的代碼有什么問題”,而不是“什么是編寫xyz的最佳方法”。
我發現錯誤的是,我正在引入一組“全局”常量。 如果我具有字段FIELD_A
其他結構,則有麻煩。 FIELD_A
應該具有結構范圍,而不是全局范圍。 這是我所做的不合標准的一大原因。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.