2

나에게 버그처럼 보이지만 어쩌면 누군가가 이것에 대해 합당한 설명을 할 것입니다. 다음GAE NDB PickleProperty for dict : 새 엔터티가 이전 속성을 사용합니까?

class Test(ndb.Model): 
    a= ndb.IntegerProperty() 
    p = ndb.PickleProperty(default={}) 

지금 수행 : 다음 코드를 고려

>> t1 = Test() 
>> t1.p['a'] = 1 
>> t1.p['b'] = 2 
{'a': 1, 'b': 2} 

여기까지, 모두 괜찮습니다. 그러나 지금 :

>> t2 = Test() 
>> t2.p 
{'a': 1, 'b': 2} 

새로운 t2 인스턴스에는 t1의 p 값이 할당 되었습니까? !!

버그 이외의 다른 설명이 있으십니까? t1의 put()을 수행하면 동작이 변경되지 않습니다. 파이썬에서

+0

@Alex Martelli DictPickleProperty는 완벽한 솔루션처럼 보였지만 포함 된 ndb Model 클래스의 새 엔터티를 만들 때 속성의 '__init__' 메서드가 호출되지 않습니다. 즉, 질문의 샘플에서 p를 DictPickleProperty()로 변경 한 다음't1 = Test()'를 인스턴스화합니다. 그러나 DictPickleProperty'의 init은 호출되지 않습니다. 내가 놓친 게 있니? – patb

답변

2

, 기본 인수는 번을 평가하는 - 그래서 당신은 사용하고 하나의dict 종류 Test의 모든 엔티티에 걸쳐 (당신의 default={} 프로세스 당 하나의 DICT, 개체 당되지 하나입니다!)하는 동일한 프로세스 내에서 발생하고 p이 명시 적으로 설정되지 않은 경우

t=Test(p={})을 입력하면 t은 괜찮습니다. dict입니다. t=Test()을 수행 한 다음 t.p = {}을 입력하면 문제가 없습니다. 그러나 엔티티의 특정 p을 설정하지 않으면 동일한 프로세스 내에서 p이 설정되지 않은 해당 종류의 모든 엔티티에서 사용되는 동일한 기본 값 dict을 사용하게됩니다 명시 적으로.

putTest 엔티티, 데이터 저장소에 어떤 일이 일어나는지 그 당시의 p의 절인 "스냅 샷"- 당신 get 다시, 그것은 그 상태로 복원, 지금은 다른 가능한 연결이 끊어집니다 default 단일 -dict -per-process를 사용합니다. 그러나 이것들은 그 모호한 사용법에서의 예외 일뿐입니다.

간단히 말해서, 변경 가능한 기본값는 파이썬에서 좋은 생각이 아니다 - 사람들은 좀처럼 올바르게 사용합니다. 그리고 적어도 다른 파이썬 호출 가능 호출만큼 ndb.PickleProperty에 대한 호출에도 적용됩니다!

추가 : 당신이 PickleProperty이 도움이 될 수 있습니다 서브 클래스, 특히 DICT를 개최하고, 너무 복잡 명시 적으로 p={} 당신이 개체의 종류를 인스턴스화 할 때마다 추가 찾기 위해 PickleProperty이 필요합니다. 즉 :

class DictPickleProperty(ndb.PickleProperty): 
    def __init__(self, **kwds): 
     kwds['default'] = kwds.get('default', {}) 
     super(DictPickleProperty, self).__init__(**kwds) 

당신이 default은 (A) 인 경우 지정 또는 dict하지 무언가로 지정 (B)는, 당신의 몫입니다하지 싶습니다. 이 간단한 예제는 (B)의 경우 특별한 것은 없습니다 - (예를 들어 default=[]은 여전히 ​​문제를 일으킴) - (A)의 경우 새로운 empy dict을 사용합니다.

다른 방법으로는 (예외를 발생시킬 것이다 그래서 [] 또는 {} 새로운 dict 빈, 그러나 많은 다른 값을 만들 것입니다) 새로운 dict에 어떠한 제공 default 값을 변환하려고 할 수 있습니다

 kwds['default'] = dict(kwds.get('default',())) 

또는 , 물론, 많은 다른 변종.

+0

@DanielRoseman, 오픈 소스이므로 쉽게 검사 할 수 있습니다. ext/ndb/model.py 클래스의'Property' 클래스에서는 880 행에 기본값이 None : self._default = default'가 아니라면 아무것도 표시되지 않습니다. 나쁜 오래된'db'를 조사하게하겠습니다. 내가 마지막으로 사용한 이후로 ... –

+0

OK, great, thanks! 그렇다면 버그는 아니지만 여전히 기대하거나 바라는 것이 아닙니다! __init __()가 대안이 될 수 있었습니까? 그러나 Ndb 인스턴스가있는 __init__은 읽기시 호출되므로 읽은 속성을 덮어 쓸 수 있습니까? – patb

+0

@DanielRoseman,'db'를 확인했습니다 - 전혀 변이가 없습니다 (유일한 기본 속성 인'ListProperty'). –