簡體   English   中英

使用有意義的字段名稱值的數組不是Python結構的pythonic?

[英]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看起來都是foobar 訪問對象變量涉及在對象的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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM