2

私が以下に持っているものよりも静的/定数であることを意図した ctypes フィールドを初期化するより良い方法はありますか?

from ctypes import *

class foo(LittleEndianStructure):
  _fields_ = [
    ("signature", c_ulonglong),
    ]

  def __init__(self):
      super(LittleEndianStructure,self).__init__()
      self.signature = 0x896489648964

f = foo()
print hex(f.signature)

たとえば、通常の python オブジェクトで行う方法と同様のことができると期待していました。

class bar:
    signature = 0x896489648964

b = bar()
print hex(b.signature)
4

1 に答える 1

2

短い答えはノーです。これはできませんし、したくないはずです。


あなたの通常の Python オブジェクト サンプルは、あなたが思っていることをしません。インスタンス属性を自動的に初期化するわけではありません。代わりにクラス属性を作成しています。

場合によっては同じように機能しますが、同じものではありません。たとえば、次のように比較します。

>>> class Foo(object):
...     bar=[]
...     def __init__(self):
...         self.baz=[]
... 
>>> f1 = Foo()
>>> f2 = Foo()
>>> f1.bar.append(100)
>>> f1.baz.append(100)
>>> f2.bar
[100]
>>> f2.baz
[]

ここで、f1f2それぞれが独自の を初期化しますが、独自の を自動的に初期化するわけではありませbaz— それらは他のすべてのインスタンスと 1つの を共有します。barbar

そして、このケースにより直接的に関連する:

>>> f1.__dict__
{'baz': [1]}

barクラス属性は の辞書の一部ではありませんf1

したがって、同じことを に変換するとctypes"signature"それをクラス属性にすると、構造体のメンバーにはなりません。つまり、各インスタンスの一部としてメモリに配置されません。それはそれを持っているという全体の目的を無効にするでしょう.


C++ を知っている場合は、C++ の用語で調べると役立つ場合があります。

上記のようなクラス属性はbar、C++ の静的メンバー変数のようなものですが、インスタンス属性は通常のインスタンス メンバー変数のようなものです。

この C++ コードでは:

struct bar {
    static const long signature = 0x896489648964;
};

…それぞれbarが実際には空の構造です。bar::signatureメモリ内の別の場所に保存されている単一のものがあります。インスタンスを介して参照できますbarが、コンパイラb1.signaturebar::signature.


* 私が「ある程度」と言った理由は、Python クラスの属性はサブクラスによってオーバーライドできますが、C++ の静的メンバーはオーバーライドできないためです。これらは実際には単なるグローバル変数であり、サブクラスによってのみ「隠す」ことができます。

于 2013-07-11T19:30:44.933 に答える