2016-07-12 4 views
0

다른 시간에 저장하고 다시로드하려는 객체의 사전을 만듭니다 ("json"모듈로 " 간물").__dict__ Python에서 메소드 호출을 허용하지 않음

저는 하나의 클래스를 만들었습니다 ("Ball"이라고합시다). 그리고 사전에는 그 클래스의 여러 인스턴스가 포함되어 있습니다. 모양은 다음과 같습니다.

my_dict = { 
      "ball1": {"size": "big", "baseball": False, etc...}, 
      "ball2": {"size": "small", "baseball": True, etc...}, 
      etc... 
      } 

"볼"클래스의 새 인스턴스를 만들 때 "my_dict"에 추가하기 만합니다.

내 "볼"클래스 나 특정 필드의 값을 변경할 수있는 방법 ... 즉이 있습니다

changeSize(self, size) 

문제 :

위해 나는 일을 할 수있는 능력을 저장을 취득하는

newBall = Ball(name) 
my_dict[name] = newBall.__dict__ 

추가 : 제대로 JSON 모듈 난은 "볼"클래스의 새 인스턴스에 다음을 수행해야했다

사전에 추가하면 JSON을 직렬화 할 수 있지만 "편집 모드"로 전환하면 메서드 (예 : changeSize (name))를 호출 할 수 없습니다. 사전과 더 이상 "볼"개체가 아닙니다.

(json 모듈을 사용하여) 저장하고 편집 할 수있는 방법을 사용하려면 어떻게해야합니까?

또한, 나는이 저장하고있는 방법은/로딩은 다음과 같다 :

out_file = open("testSave.json"), "w") 
json.dump(my_dict, out_file, indent=4) 
out_file.close() 

in_file = open("testSave.json", "r") 
my_dict = json.load(in_file) 
in_file.close() 

감사합니다!

답변

1

궁극적으로 json은 임의의 파이썬 개체를 직렬화하는 것을 지원하지 않습니다. 그렇게하고 싶다면 pickle을보십시오.

는 다른 방법으로는 dict에서 값을 초기화합니다 당신의 Ball에 다른 생성자를 만들 수 있습니다

나는 이것을 Ball 생성자 0 인수로 호출 할 수 있다는 가정하에 작성했습니다
class Ball(object): 

    @classmethod 
    def from_json(self, dictionary): 
     b = cls() 
     b.__dict__.update(dictionary) 
     return b 

    ... 

- 그렇지 않은 경우 코드를 수정하거나 __init__이 "공상"(json 직렬화 가능 속성 설정 제외)을 수행하는 경우 코드를 수정해야 할 수 있습니다.

class Ball(object): 
    def __init__(self, name, foo, bar): 
     self.name = name 
     self.foo = foo 
     self.bar = bar 

    def to_dict(self): 
     return self.__dict__ 

    @classmethod 
    def from_dict(cls, dictionary): 
     self = cls.__new__(cls) 
     self.__dict__.update(dictionary) 
     return self 

    def __str__(self): 
     return 'Ball(%r, %r, %r)' % (self.name, self.foo, self.bar) 


b = Ball('HockyPuck', 'flat', 'NotABall') 
d = b.to_dict() 
bb = Ball.from_dict(d) 

print(bb) 

이 python2.x 및 3.x에서 모두 작동합니다 __init__의 인수의 요구 주위에 한 가지 방법은 인스턴스를 생성 __new__을 사용하고 바로 클래스 사전을 업데이트하여 구성원을 채우는 것입니다

+0

'Ball'생성자는 최소한 이름을 필요로합니다 (그러나 프로그램에서 프롬프트되므로 프롬프트가 나타납니다). 만약 내가 기본적으로'pickle'으로 이미하고있는 것과 똑같은 일을했다면 말 하겠니? 안전성이 낮아서 json 방식을 배우려고 한 이유입니다. 또한'json'을 계속 사용한다면,'decorator '를 왜 사용하는지에 대한 간단한 설명을 주실 수 있습니까? 나는 그들에 대한 큰 이해가 없다. 고마워요! – AmericanMade

+0

@AmericanMade - 당신은'b = cls (dictionary.get ('name'))'또는 유사한 것을 할 수있을 것입니다. 재 :'피클'- 확실한 보안 문제가 있습니다. 완전히 신뢰하지 않으면 무언가를 unpickle하지 마십시오. '@ classmethod'에 대해서, 그것은 from_json에서'cls'가 클래스의 인스턴스가 아닌 _class_가되도록합니다. – mgilson

관련 문제