2011-12-20 11 views
3

混乱するタイトルに申し訳ありません。Cマクロに似た名前の関数をPythonで作成することは可能ですか?

Iは、次の操作を実行したい:

(Lispで defstructに類似)
def mkstruct(structname, field_dict): 
    # create a function called "structname" and get/set functions 
    # called "structname_get(s, field_name)" and "structname_set(s, field_name, value)" 

# Create a struct "lstnode" 
mkstruct("lstnode", {ndkey : 0, nxt: None}) 
# Make a new struct 
node = lstnode() 
node_set(node, "ndkey", 5) 
v = node_get(node, "ndkey") # v should be 5 

これは定義マクロとCで行うことができます。私が作成している "構造体"は、データベース(この場合は何らかの形式のテキストファイル)に "結び付けられる"ため、クラスを使用しない理由があります。そして、私はオブジェクトに関連付けられたメモリを使いたくないです - 私は構造体を数値(オブジェクトID)として表現します

+0

ですから、実際のメモリがありません場合は、これらのゲッターとセッターは何をすべきかをしたいですか? – robert

+5

あなたはあなたの嫌悪感をより具体的に表現できますか?関数を辞書に入れると、本質的にクラスを改革しただけです。これは、これが向かうところのように聞こえる。 – nmichaels

+0

私は巨大な木構造を持っています。オブジェクトの代わりにOIDを使用することで逃げることができれば、結果としてオブジェクト参照を使用していません。すべてのオブジェクトへのアクセスは、代わりにデータベース操作(ルックアップと更新)に変換されます。 – dividebyzero

答えて

1

これはあなたが望む方向へのステップでなければなりません:

def mkstruct(name, attrs): 
    def init(self): 
     self.id = # not sure how you want to get the id 

    def getattr(self, attr): 
     if attr not in attrs: 
      raise AttributeError(attr) 
     # put your database lookup statement here 

    def setattr(self, attr, value): 
     if attr not in attrs: 
      raise AttributeError(attr) 
     # put your database update statement here 

    return type(
     name, 
     (object,), 
     __init__=init, 
     __getattr__=getattr, 
     __setattr__=setattr) 

lstnode = mkstruct("lstnode", ("ndkey", "nxt")) 
1

あなたが探していることは、すでにビルトインtypeによって提供されていることを私に見える:

def mkstruct(structname, field_dict): 
    return type(structname, (object,), field_dict) 

lstnode = mkstruct("lstnode", {'ndkey' : 0, 'nxt': None}) 
node = lstnode() 
node.ndkey = 5 
v = node.ndkey 

あなたは構造体のメンバーであるfield_dictでちょうどキーが必要な場合は、あなたがすることができます'__slots__'にを追加。

注:これはセッターやゲッターを実装していませんが、既にコメントによって指摘されているように、クラスを使用する場合は実際には必要ありません。

0

これは、Pythonでやるのは簡単ではないようです。グローバルな名前空間に内部関数を追加する唯一の方法は、globals()dictを変更することです。これはむしろ面倒です。私自身の問題については

>>> def mkfunc(funcname): 
... def func(): 
...  print "my name is %s" % funcname 
... func.__name__ = funcname 
... return func 
... 
>>> mkfunc("abc") 
<function abc at 0xb773ae64> 
>>> globals()["abc"] = mkfunc("abc") 
>>> abc() 
my name is abc 

、私は次のことを行うには満足して:

def mkstruct(fields): 
    def maker(args): 
     # validate @args against @fields 
     oid = db_insert_row(fields) 
     return oid 
    def getter(oid, fieldname): 
     rec = db_retrieve(oid) 
     return rec[fieldname] 
    def setter(oid, fieldname, value): 
     db_update(oid, fieldname, value) 
    return (maker, getter, setter,) 

lstnode, lstnode_get, lstnode_set = mkstruct({nodekey: 0, nxt: None}) 
n = lstnode(nodekey=5) 
関連する問題