次のように機能するものを実装したいと思います。
memo = Note("memo",5)
report = Note("report",20)
notebook = Notebook(memo,report)
print str(notebook.memo) # 5 expected
print str(notebook.report) # 20 expected
に触発されました: http://znasibov.info/blog/html/2010/03/10/python-classes-dynamic-properties.html および 動的な名前で property() を実装する方法 (python) 、次のコードを実装しました:
class Note:
def __init__(self,name,size):
self.name = name
self.size = size
class Notebook(object):
def __new__(cls,*notes):
notebook = object.__new__(cls)
setattr(notebook,'_notes',{note.name : note.size for note in notes})
functions = [lambda notebook : notebook._notes[note.name] for note in notes]
for note,function in zip(notes,functions) :
#version 1
setattr(notebook.__class__, note.name, property(function))
#version 2 -- note : __class__ removed
#setattr(notebook, note.name, property(function))
return notebook
注: この最小限のコードでは、__new__
代わりに を使用する__init__
ことは正当化されないことはわかっていますが、これは後で のサブクラスを使用するときに必要になります。Notebook
バージョン 1: 1. を使用すると、印刷される代わりに、5
and20
が印刷され20
ます20
。理由がわかりません。関数を印刷すると、アドレスが異なる関数の配列が表示されます。2.__class__
上記のブログ エントリに触発されて使用しましたが、それが何をするのかわかりません。プロパティをクラスプロパティにしますか?(私の場合、これは本当に悪いことです)
バージョン 2 を使用する場合: のようなものを出力しますproperty object at 0x7fb86a9d9b50
。これは理にかなっているように思えますが、バージョン 1 で同じものが出力されない理由がよくわかりません。
いずれかのバージョン (または別の完全に異なるアプローチ) を使用して、これを修正する方法はありますか?
編集
問題を解決するための興味深い答えが提案されました。ここに対応するコード:
class Note:
def __init__(self,name,value):
self.name = name
self.size = value
def _get_size(self,notebook_class=None): return self.size+1
class Notebook(object):
def __new__(cls,*notes):
notebook = object.__new__(cls)
notebook._notes = {note.name : note.size for note in notes}
for note in notes : setattr(notebook.__class__, note.name, property(note._get_size))
return notebook
問題は次のとおりです。現在、このテストコードは目的の出力を提供していません:
memo1 = Note("memo",5)
report1 = Note("report",20)
notebook1 = Notebook(memo1,report1)
print str(notebook1.memo) # print 6 as expected (function of Note return size+1)
print str(notebook1.report) # print 21 as expected
memo2 = Note("memo",35)
report2 = Note("report",40)
notebook2 = Notebook(memo2,report2)
print str(notebook2.memo) # print 36 as expected
print str(notebook2.report) # print 41 expected
print str(notebook1.memo) # does not print 6 but 36 !
print str(notebook1.report) # does not print 21 but 41 !
プロパティがクラスに追加されたので、これは予想されていたことだと思います.... とにかく、この問題を克服するには?