<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>Jsonmodel on 编程技术记录</title>
    <link>https://blog.z6z8.cn/tags/jsonmodel/</link>
    <description>Recent content in Jsonmodel on 编程技术记录</description>
    <generator>Hugo</generator>
    <language>zh-Hans</language>
    <lastBuildDate>Mon, 28 Oct 2019 04:48:44 +0000</lastBuildDate>
    <atom:link href="https://blog.z6z8.cn/tags/jsonmodel/feed.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Python JSONModel的实现思路</title>
      <link>https://blog.z6z8.cn/2019/10/28/python-jsonmodel%E7%9A%84%E5%AE%9E%E7%8E%B0%E6%80%9D%E8%B7%AF/</link>
      <pubDate>Mon, 28 Oct 2019 04:48:44 +0000</pubDate>
       <guid isPermaLink="false">http://blog.z6z8.cn/?p=527</guid> 
      <description>&lt;p&gt;JSONModel，模型和JSON数据之间相互转换，或者模型和JSON数据的序列化、反序列化。&lt;/p&gt;
&lt;p&gt;不同语言实现细节不一样，也并不是所有语言都可以实现。这里我参考Objective-C语言的JSONModel实现机制，设计了一种Python运行时JSON和Model的互转方案思路。&lt;/p&gt;
&lt;h1 id=&#34;object类&#34;&gt;object类&lt;/h1&gt;
&lt;p&gt;用dir打印object&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;gt;&amp;gt;&amp;gt; dir&lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;object&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;__class__&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;__delattr__&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;__doc__&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;__format__&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;__getattribute__&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;__hash__&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;__init__&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;__new__&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;__reduce__&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;__reduce_ex__&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;__repr__&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;__setattr__&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;__sizeof__&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;__str__&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;__subclasshook__&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;挨个找，看到两个方法 &lt;code&gt;__setattr__&lt;/code&gt; 和 &lt;code&gt;__getattribute__&lt;/code&gt;，看名字也大概知道用途,基本意思就是可以通过 &lt;code&gt;__setattr__&lt;/code&gt; 和 &lt;code&gt;__getattribute__ &lt;/code&gt; 访问object实例的属性值。&lt;/p&gt;
&lt;p&gt;具体可参考https://www.cnblogs.com/elie/p/6685429.html&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;__setattr__&lt;/code&gt; 如果类自定义了 &lt;code&gt;__setattr__&lt;/code&gt; 方法，当通过实例获取属性尝试赋值时，就会调用 &lt;code&gt;__setattr__&lt;/code&gt;。常规的对实例属性赋值，被赋值的属性和值会存入实例属性字典 &lt;code&gt;__dict__&lt;/code&gt; 中；如下类自定义了 &lt;code&gt;__setattr__&lt;/code&gt;,对实例属性的赋值就会调用它。类定义中的self.attr也同样，所以在 &lt;code&gt;__setattr__&lt;/code&gt; 下还有self.attr的赋值操作就会出现无线递归的调用 &lt;code&gt;__setattr__&lt;/code&gt; 的情况。自己实现 &lt;code&gt;__setattr__&lt;/code&gt; 有很大风险，一般情况都还是继承object类的 &lt;code&gt;__setattr__&lt;/code&gt; 方法。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;__getattribute__ &lt;/code&gt; 实例instance通过instance.name访问属性name， &lt;code&gt;__getattribute__&lt;/code&gt; 方法一直会被调用，无论属性name是否追溯到。如果类还定义了 &lt;code&gt;__getattr__&lt;/code&gt; 方法，除非通过 &lt;code&gt;__getattribute__&lt;/code&gt; 显式的调用它，或者 &lt;code&gt;__getattribute__&lt;/code&gt; 方法出现AttributeError错误，否则 &lt;code&gt;__getattr__&lt;/code&gt; 方法不会被调用了。如果在 &lt;code&gt;__getattribute__(self, attr)&lt;/code&gt; 方法下存在通过self.attr访问属性，会出现无限递归错误。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&#34;步骤&#34;&gt;步骤&lt;/h1&gt;
&lt;p&gt;只讨论最小场景（当然可以自行扩展）&lt;/p&gt;
&lt;h2 id=&#34;json---model&#34;&gt;json -&amp;gt; model&lt;/h2&gt;
&lt;p&gt;这里假设json是一个字典，且没有嵌套情况。
并且假设应知道model的类名，一个字典对应一个model。&lt;/p&gt;
&lt;p&gt;遍历json所有key ,然后按照key名称给model的属性赋值。&lt;/p&gt;
&lt;p&gt;示意代码&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;dict &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; json数据
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;model&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;类的实例
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; (key,value) &lt;span style=&#34;color:#f92672&#34;&gt;in&lt;/span&gt; dict&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;items():
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            model&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;__setattr__&lt;/span&gt;(key,value)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;model---json&#34;&gt;model -&amp;gt; json&lt;/h2&gt;
&lt;p&gt;这里假设model的所有属性都能转化为对应的json数据，且没有嵌套。
这里，还需要借助 &lt;code&gt;__dict__&lt;/code&gt; 函数&lt;/p&gt;</description>
    </item>
  </channel>
</rss>
