-1

アプリケーションのデバッグ中に予期しない動作が見つかりました。以下に説明する結果が得られる理由を誰かが知っていますか?

from google.appengine.ext import ndb

class Person(ndb.Model):
  name = ndb.StringProperty()
  shared = ndb.BooleanProperty(default=False)

class Department(ndb.Model):
  name = ndb.StringProperty()
  persons = ndb.KeyProperty(kind=Person, repeated=True)

  @property
  def all_department_resources(self):    
    emp_list = self.persons
    for p in Person.query().filter(Person.shared == True):
      emp_list.append(p.key)
    return emp_list 

p1 = Person(name='Jane').put()
p2 = Person(name='Siri').put()
p3 = Person(name='Joe', shared=True).put()
Department(name='Finance',persons=[p1,p2]).put()

print '\n*First run*'
for d in Department.query():
  print '>>' + d.name
  for p in d.all_department_resources:   
    print p.get().name

print '\n*Second run:*'
for d in Department.query():
  print '>>' + d.name
  for p in d.all_department_resources:   
    print p.get().name

出力:

*First run*
>>Finance
Jane
Siri
Joe

*Second run:*
>>Finance
Jane
Siri
Joe
Joe

私の質問は簡単です: 2 番目のジョーはどこから来たのですか?

4

2 に答える 2

3

all_department_resourcesJoe をself.personsリストに追加します。2 回目の呼び出しで、もう一度追加します。この動作を確認するには、テキスト ブロックを 3 回実行して 3 つの Joe を見つけます。

なんで?

emp_list = self.persons

リストのコピーは作成しませんが、それを参照します。あなたがすることもすべてemp_list起こりself.personsます。

私はそれについて何ができますか? どちらかでコピーを作成します

emp_list = list(self.persons)

または、クエリを return ステートメントに追加することもできます。

  @property
  def all_department_resources(self):    
    return self.persons + Person.query().filter(Person.shared == True)
于 2012-09-06T11:23:22.280 に答える
0

実行するたびfor p in d.all_department_resources:に実行されます

for p in Person.query().filter(Person.shared == True):
    emp_list.append(p.key)`

のリストに Joe のキーが追加されますPersons

于 2012-09-06T11:22:12.180 に答える