SlideShare a Scribd company logo
1 of 26
Download to read offline
茴香豆的茴有几种写法
 记Python的⼀一个客户端实现
     dreampuf Jul, 2012
本地调用


                main




       printf          scanf
远程调用


                  Client

             Protocol Stream

       ServerA             ServerB
Esty-python
   class MockAPI(API):
       api_url = 'http://host'
       api_version = 'v1'
       def etsy_home(self):
           return Test.scratch_dir
       def get_method_table(self, *args):
           return [{'name': 'testMethod',
                    'uri': '/test/{test_id}',
                    'http_method': 'GET',
                    'params': {
                        'limit': 'int',
                        'test_id': 'user_id_or_name',
                        'offset': 'int',
                        'fizz': 'enum(foo, bar, baz)',
                        'buzz': 'float',
                        'blah': 'unknown type',
                        'kind': 'string',
                        },
                    'type': 'int',
                    'description': 'test method.'}]
       def _get_url(self, url, http_method, content_type, body):
           return '{ "count": 1, "results": [3] }'
Esty-python
   class MockAPI(API):
       api_url = 'http://host'
       api_version = 'v1'
       def etsy_home(self):
           return Test.scratch_dir
       def get_method_table(self, *args):
           return [{'name': 'testMethod',
                    'uri': '/test/{test_id}',
                    'http_method': 'GET',                     重用
      不直观           'params': {
                        'limit': 'int',                       不依赖URL
缺乏语法检查                  'test_id': 'user_id_or_name',
                        'offset': 'int',                      类型验证
    不易调试                'fizz': 'enum(foo, bar, baz)',
                        'buzz': 'float',
                        'blah': 'unknown type',
                                                              URL拓展
                        'kind': 'string',
                        },
                    'type': 'int',
                    'description': 'test method.'}]
       def _get_url(self, url, http_method, content_type, body):
           return '{ "count": 1, "results": [3] }'
GuokrAPI v1


          class GuokrAPI(API):
              HOST = "http://localhost/"
              METHODS = [{
                   "name": "get_tag",
                   "url": "tags",
                   "method": "GET",
                   "description": "Get the tag instance list",
              }, {
                   "name": "get_tags",
                   "url": "tags/%(tagname)s",
                   "method": "GET",
                   "description": "Get a tag instance",
              }]
GuokrAPI v1


          class GuokrAPI(API):
              HOST = "http://localhost/"
              METHODS = [{
    不直观            "name": "get_tag",
                   "url": "tags",
                                                                 重用
                   "method": "GET",
缺乏语法检查             "description": "Get the tag instance list",   不依赖URL
              }, {
   不易调试            "name": "get_tags",                           URLLIB3
                   "url": "tags/%(tagname)s",
   类型验证            "method": "GET",                              URL拓展
                   "description": "Get a tag instance",
              }]
GuokrAPI v2
   tagging = guokr.type(                import guokr
       'tagging'                        import minerva.types as minerva
   ).fields({
       'id': 'int',                     tags = guokr.resources([
       'tag': 'string',                     minerva.tag
       'taggable': 'taggable',          ])
       'tag': 'string',
       'user': 'ukey',                  taggings = guokr.resources([
       'date_create': 'datetime',           minerva.tag,
       'date_deleted': 'datetime',          minerva.taggable,
   }).keys([                            ]).namespace(
     'id'                                   'taggings'
   ]).end()                             )


                 mercury.group.mixin(minerva.taggable)

                 # POST on url /tags
                 call = resources.tags.create().format('jsonp')

                 # POST on url /taggings/tags/科学/group/654321
                 call = resources.taggings.update({
                     'tag': '科学',
                     'taggable': group,
                     'user': 'afsrgx',
                 })
GuokrAPI v2
   tagging = guokr.type(                import guokr
       'tagging'                        import minerva.types as minerva
   ).fields({
       'id': 'int',                     tags = guokr.resources([
       'tag': 'string',                     minerva.tag
       'taggable': 'taggable',          ])
       'tag': 'string',
       'user': 'ukey',                  taggings = guokr.resources([
       'date_create': 'datetime',           minerva.tag,
       'date_deleted': 'datetime',          minerva.taggable,
   }).keys([                            ]).namespace(
     'id'                                   'taggings'
   ]).end()                             )


                 mercury.group.mixin(minerva.taggable)
                                                                   重用
                 # POST on url /tags
  URL拓展          call = resources.tags.create().format('jsonp')
                                                                   类型验证
  抽象繁多           # POST on url /taggings/tags/科学/group/654321      链式语法
                 call = resources.taggings.update({
                     'tag': '科学',                                  清晰
                     'taggable': group,
                     'user': 'afsrgx',
                 })
GuokrAPI v2
GuokrAPI v2




              Pyt hon
GuokrAPI v2




              Py   t hon   ic
GuokrAPI v3

  TUPLE_TAGGINGABLE = ("article", "post", "blog", "group", "question")
  class GuokrAPI(API):
      HOST = "http://localhost:5000/"

      @GET("tags/%(tag)s")
      def get_tag(tag): pass
      @GET("tags/%(tag)s/feeds")
      def get_tag_feeds(tag, filter=str): pass
      @POST("tags/")
      def add_tag(tag, synonym=str, logo=str, description=str): pass
      @POST("tag/%(tag)s")
      def post_tag(tag, logo=str, description=str): pass

   class GuokrCMSAPI(GuokrAPI):
      @GET("cms/tags/filter:%(prefix)s")
      def get_tag_prefix(prefix): pass
      #Duplicate
      #@POST("cms/tags")
      #def add_tag(self, tag, synonym=None, logo=None, description=None): pass
      @POST("cms/tags/%(tag)s")
      def post_tag(tag, logon=str, synonyms=str): pass #synonyms VS synonym
      @POST("cms/tags/%(tag)s/lock")
GuokrAPI v3

  TUPLE_TAGGINGABLE = ("article", "post", "blog", "group", "question")
  class GuokrAPI(API):
      HOST = "http://localhost:5000/"

      @GET("tags/%(tag)s")                                               重用
      def get_tag(tag): pass
      @GET("tags/%(tag)s/feeds")                                         类型验证
      def get_tag_feeds(tag, filter=str): pass
      @POST("tags/")                                                     清晰
      def add_tag(tag, synonym=str, logo=str, description=str): pass
      @POST("tag/%(tag)s")                                               调试/直观
      def post_tag(tag, logo=str, description=str): pass

   class GuokrCMSAPI(GuokrAPI):
      @GET("cms/tags/filter:%(prefix)s")
      def get_tag_prefix(prefix): pass
      #Duplicate
      #@POST("cms/tags")
      #def add_tag(self, tag, synonym=None, logo=None, description=None): pass
      @POST("cms/tags/%(tag)s")
      def post_tag(tag, logon=str, synonyms=str): pass #synonyms VS synonym
      @POST("cms/tags/%(tag)s/lock")
结论

•统⼀一   随时注意前后接口⼀一致
•抽象    隐藏不必要的细节
•充要    只接受充分且必须的参数
•直观    对人友好,对机器友好(调试)
•原生    Pythonic
DATA ENTRY
Data Entry v1




                a = (1, 2, 3)
Data Entry v2




                a = {“a”:1,
                     “b”:2,
                     “c”:3)
Data Entry v3




class uDict(dict):
    def __getattr__(self, name):
        return self.__getitem__(name)
Data Entry v4


class uDict(dict):
    def __getattr__(self, name, default=None):
        try:
             return self.__getitem__(name)
        except KeyError:
             return default

a = uDict(a=1, b=2, c=3)
print a.b
print a.g
Data Entry v5




       class Entry(object):
           def __init__(self, a, b, c):
               self.a = a
               self.b = b
               self.c = c
Data Entry v6




     from collections import namedtuple
     Entry = namedtuple("Entry", "a b c")
     a = Entry(a=1, b=2, c=3)
Data Entry v7




class Entry(namedtuple("Entry", "a b c")):
    def __new__(cls, a=None, b=None, c=None):
        return super(Entry, cls).__new__(cls, a, b, c)
谢谢!
REFERENCE
•Etsy-python
https://github.com/mcfunley/etsy-python
•Lambda Picture
http://www.flickr.com/photos/rofi/2097239111/

More Related Content

What's hot

Designing Opeation Oriented Web Applications / YAPC::Asia Tokyo 2011
Designing Opeation Oriented Web Applications / YAPC::Asia Tokyo 2011Designing Opeation Oriented Web Applications / YAPC::Asia Tokyo 2011
Designing Opeation Oriented Web Applications / YAPC::Asia Tokyo 2011
Masahiro Nagano
 
Crazy things done on PHP
Crazy things done on PHPCrazy things done on PHP
Crazy things done on PHP
Taras Kalapun
 
Ruby Development and MongoMapper (John Nunemaker)
Ruby Development and MongoMapper (John Nunemaker)Ruby Development and MongoMapper (John Nunemaker)
Ruby Development and MongoMapper (John Nunemaker)
MongoSF
 

What's hot (18)

Designing Opeation Oriented Web Applications / YAPC::Asia Tokyo 2011
Designing Opeation Oriented Web Applications / YAPC::Asia Tokyo 2011Designing Opeation Oriented Web Applications / YAPC::Asia Tokyo 2011
Designing Opeation Oriented Web Applications / YAPC::Asia Tokyo 2011
 
Mongoskin - Guilin
Mongoskin - GuilinMongoskin - Guilin
Mongoskin - Guilin
 
PHP 5.4
PHP 5.4PHP 5.4
PHP 5.4
 
Doctrine MongoDB ODM (PDXPHP)
Doctrine MongoDB ODM (PDXPHP)Doctrine MongoDB ODM (PDXPHP)
Doctrine MongoDB ODM (PDXPHP)
 
Crazy things done on PHP
Crazy things done on PHPCrazy things done on PHP
Crazy things done on PHP
 
PHP 7 – What changed internally? (Forum PHP 2015)
PHP 7 – What changed internally? (Forum PHP 2015)PHP 7 – What changed internally? (Forum PHP 2015)
PHP 7 – What changed internally? (Forum PHP 2015)
 
Modern Getopt for Command Line Processing in Perl
Modern Getopt for Command Line Processing in PerlModern Getopt for Command Line Processing in Perl
Modern Getopt for Command Line Processing in Perl
 
The state of your own hypertext preprocessor
The state of your own hypertext preprocessorThe state of your own hypertext preprocessor
The state of your own hypertext preprocessor
 
Electrify your code with PHP Generators
Electrify your code with PHP GeneratorsElectrify your code with PHP Generators
Electrify your code with PHP Generators
 
Testing Web Applications with GEB
Testing Web Applications with GEBTesting Web Applications with GEB
Testing Web Applications with GEB
 
Ruby Development and MongoMapper (John Nunemaker)
Ruby Development and MongoMapper (John Nunemaker)Ruby Development and MongoMapper (John Nunemaker)
Ruby Development and MongoMapper (John Nunemaker)
 
Can't Miss Features of PHP 5.3 and 5.4
Can't Miss Features of PHP 5.3 and 5.4Can't Miss Features of PHP 5.3 and 5.4
Can't Miss Features of PHP 5.3 and 5.4
 
Command Bus To Awesome Town
Command Bus To Awesome TownCommand Bus To Awesome Town
Command Bus To Awesome Town
 
Teaching Your Machine To Find Fraudsters
Teaching Your Machine To Find FraudstersTeaching Your Machine To Find Fraudsters
Teaching Your Machine To Find Fraudsters
 
Spring data iii
Spring data iiiSpring data iii
Spring data iii
 
WordPress Cuztom Helper
WordPress Cuztom HelperWordPress Cuztom Helper
WordPress Cuztom Helper
 
deepjs - tools for better programming
deepjs - tools for better programmingdeepjs - tools for better programming
deepjs - tools for better programming
 
360|iDev
360|iDev360|iDev
360|iDev
 

Viewers also liked

The introduction of data visualization
The introduction of data visualizationThe introduction of data visualization
The introduction of data visualization
dreampuf
 

Viewers also liked (8)

The introduction of data visualization
The introduction of data visualizationThe introduction of data visualization
The introduction of data visualization
 
Refactoring
RefactoringRefactoring
Refactoring
 
Communication with python_http_module
Communication with python_http_moduleCommunication with python_http_module
Communication with python_http_module
 
Python magicmethods
Python magicmethodsPython magicmethods
Python magicmethods
 
Machine learning share No.1
Machine learning share No.1Machine learning share No.1
Machine learning share No.1
 
Python profiling
Python profilingPython profiling
Python profiling
 
A short introduction of D3js
A short introduction of D3jsA short introduction of D3js
A short introduction of D3js
 
The Outcome Economy
The Outcome EconomyThe Outcome Economy
The Outcome Economy
 

Similar to Python client api

前端MVC 豆瓣说
前端MVC 豆瓣说前端MVC 豆瓣说
前端MVC 豆瓣说
Ting Lv
 
用Tornado开发RESTful API运用
用Tornado开发RESTful API运用用Tornado开发RESTful API运用
用Tornado开发RESTful API运用
Felinx Lee
 
Be RESTful (Symfony Camp 2008)
Be RESTful (Symfony Camp 2008)Be RESTful (Symfony Camp 2008)
Be RESTful (Symfony Camp 2008)
Fabien Potencier
 

Similar to Python client api (20)

Let's read code: the python-requests library
Let's read code: the python-requests libraryLet's read code: the python-requests library
Let's read code: the python-requests library
 
前端MVC 豆瓣说
前端MVC 豆瓣说前端MVC 豆瓣说
前端MVC 豆瓣说
 
Grails 1.2 探検隊 -新たな聖杯をもとめて・・・-
Grails 1.2 探検隊 -新たな聖杯をもとめて・・・-Grails 1.2 探検隊 -新たな聖杯をもとめて・・・-
Grails 1.2 探検隊 -新たな聖杯をもとめて・・・-
 
Recent Changes to jQuery's Internals
Recent Changes to jQuery's InternalsRecent Changes to jQuery's Internals
Recent Changes to jQuery's Internals
 
XamarinとAWSをつないでみた話
XamarinとAWSをつないでみた話XamarinとAWSをつないでみた話
XamarinとAWSをつないでみた話
 
用Tornado开发RESTful API运用
用Tornado开发RESTful API运用用Tornado开发RESTful API运用
用Tornado开发RESTful API运用
 
Implicit parameters, when to use them (or not)!
Implicit parameters, when to use them (or not)!Implicit parameters, when to use them (or not)!
Implicit parameters, when to use them (or not)!
 
Blog Hacks 2011
Blog Hacks 2011Blog Hacks 2011
Blog Hacks 2011
 
What's new in Django 1.2?
What's new in Django 1.2?What's new in Django 1.2?
What's new in Django 1.2?
 
Тестирование и Django
Тестирование и DjangoТестирование и Django
Тестирование и Django
 
Bonnes pratiques de développement avec Node js
Bonnes pratiques de développement avec Node jsBonnes pratiques de développement avec Node js
Bonnes pratiques de développement avec Node js
 
Scalable web application architecture
Scalable web application architectureScalable web application architecture
Scalable web application architecture
 
Be RESTful (Symfony Camp 2008)
Be RESTful (Symfony Camp 2008)Be RESTful (Symfony Camp 2008)
Be RESTful (Symfony Camp 2008)
 
Objective-c Runtime
Objective-c RuntimeObjective-c Runtime
Objective-c Runtime
 
MongoDB + Java - Everything you need to know
MongoDB + Java - Everything you need to know MongoDB + Java - Everything you need to know
MongoDB + Java - Everything you need to know
 
Mongo+java (1)
Mongo+java (1)Mongo+java (1)
Mongo+java (1)
 
GraphQL Los Angeles Meetup Slides
GraphQL Los Angeles Meetup SlidesGraphQL Los Angeles Meetup Slides
GraphQL Los Angeles Meetup Slides
 
Simplifying Persistence for Java and MongoDB with Morphia
Simplifying Persistence for Java and MongoDB with MorphiaSimplifying Persistence for Java and MongoDB with Morphia
Simplifying Persistence for Java and MongoDB with Morphia
 
Open Source Search: An Analysis
Open Source Search: An AnalysisOpen Source Search: An Analysis
Open Source Search: An Analysis
 
Let's read code: python-requests library
Let's read code: python-requests libraryLet's read code: python-requests library
Let's read code: python-requests library
 

Recently uploaded

Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
Joaquim Jorge
 

Recently uploaded (20)

Advantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your BusinessAdvantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your Business
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
 
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 

Python client api

  • 2.
  • 3. 本地调用 main printf scanf
  • 4. 远程调用 Client Protocol Stream ServerA ServerB
  • 5. Esty-python class MockAPI(API): api_url = 'http://host' api_version = 'v1' def etsy_home(self): return Test.scratch_dir def get_method_table(self, *args): return [{'name': 'testMethod', 'uri': '/test/{test_id}', 'http_method': 'GET', 'params': { 'limit': 'int', 'test_id': 'user_id_or_name', 'offset': 'int', 'fizz': 'enum(foo, bar, baz)', 'buzz': 'float', 'blah': 'unknown type', 'kind': 'string', }, 'type': 'int', 'description': 'test method.'}] def _get_url(self, url, http_method, content_type, body): return '{ "count": 1, "results": [3] }'
  • 6. Esty-python class MockAPI(API): api_url = 'http://host' api_version = 'v1' def etsy_home(self): return Test.scratch_dir def get_method_table(self, *args): return [{'name': 'testMethod', 'uri': '/test/{test_id}', 'http_method': 'GET', 重用 不直观 'params': { 'limit': 'int', 不依赖URL 缺乏语法检查 'test_id': 'user_id_or_name', 'offset': 'int', 类型验证 不易调试 'fizz': 'enum(foo, bar, baz)', 'buzz': 'float', 'blah': 'unknown type', URL拓展 'kind': 'string', }, 'type': 'int', 'description': 'test method.'}] def _get_url(self, url, http_method, content_type, body): return '{ "count": 1, "results": [3] }'
  • 7. GuokrAPI v1 class GuokrAPI(API): HOST = "http://localhost/" METHODS = [{ "name": "get_tag", "url": "tags", "method": "GET", "description": "Get the tag instance list", }, { "name": "get_tags", "url": "tags/%(tagname)s", "method": "GET", "description": "Get a tag instance", }]
  • 8. GuokrAPI v1 class GuokrAPI(API): HOST = "http://localhost/" METHODS = [{ 不直观 "name": "get_tag", "url": "tags", 重用 "method": "GET", 缺乏语法检查 "description": "Get the tag instance list", 不依赖URL }, { 不易调试 "name": "get_tags", URLLIB3 "url": "tags/%(tagname)s", 类型验证 "method": "GET", URL拓展 "description": "Get a tag instance", }]
  • 9. GuokrAPI v2 tagging = guokr.type( import guokr     'tagging' import minerva.types as minerva ).fields({     'id': 'int', tags = guokr.resources([     'tag': 'string',     minerva.tag     'taggable': 'taggable', ])     'tag': 'string',     'user': 'ukey', taggings = guokr.resources([     'date_create': 'datetime',     minerva.tag,     'date_deleted': 'datetime',     minerva.taggable, }).keys([ ]).namespace(   'id'     'taggings' ]).end() ) mercury.group.mixin(minerva.taggable) # POST on url /tags call = resources.tags.create().format('jsonp') # POST on url /taggings/tags/科学/group/654321 call = resources.taggings.update({     'tag': '科学',     'taggable': group,     'user': 'afsrgx', })
  • 10. GuokrAPI v2 tagging = guokr.type( import guokr     'tagging' import minerva.types as minerva ).fields({     'id': 'int', tags = guokr.resources([     'tag': 'string',     minerva.tag     'taggable': 'taggable', ])     'tag': 'string',     'user': 'ukey', taggings = guokr.resources([     'date_create': 'datetime',     minerva.tag,     'date_deleted': 'datetime',     minerva.taggable, }).keys([ ]).namespace(   'id'     'taggings' ]).end() ) mercury.group.mixin(minerva.taggable) 重用 # POST on url /tags URL拓展 call = resources.tags.create().format('jsonp') 类型验证 抽象繁多 # POST on url /taggings/tags/科学/group/654321 链式语法 call = resources.taggings.update({     'tag': '科学', 清晰     'taggable': group,     'user': 'afsrgx', })
  • 12. GuokrAPI v2 Pyt hon
  • 13. GuokrAPI v2 Py t hon ic
  • 14. GuokrAPI v3 TUPLE_TAGGINGABLE = ("article", "post", "blog", "group", "question") class GuokrAPI(API): HOST = "http://localhost:5000/" @GET("tags/%(tag)s") def get_tag(tag): pass @GET("tags/%(tag)s/feeds") def get_tag_feeds(tag, filter=str): pass @POST("tags/") def add_tag(tag, synonym=str, logo=str, description=str): pass @POST("tag/%(tag)s") def post_tag(tag, logo=str, description=str): pass class GuokrCMSAPI(GuokrAPI): @GET("cms/tags/filter:%(prefix)s") def get_tag_prefix(prefix): pass #Duplicate #@POST("cms/tags") #def add_tag(self, tag, synonym=None, logo=None, description=None): pass @POST("cms/tags/%(tag)s") def post_tag(tag, logon=str, synonyms=str): pass #synonyms VS synonym @POST("cms/tags/%(tag)s/lock")
  • 15. GuokrAPI v3 TUPLE_TAGGINGABLE = ("article", "post", "blog", "group", "question") class GuokrAPI(API): HOST = "http://localhost:5000/" @GET("tags/%(tag)s") 重用 def get_tag(tag): pass @GET("tags/%(tag)s/feeds") 类型验证 def get_tag_feeds(tag, filter=str): pass @POST("tags/") 清晰 def add_tag(tag, synonym=str, logo=str, description=str): pass @POST("tag/%(tag)s") 调试/直观 def post_tag(tag, logo=str, description=str): pass class GuokrCMSAPI(GuokrAPI): @GET("cms/tags/filter:%(prefix)s") def get_tag_prefix(prefix): pass #Duplicate #@POST("cms/tags") #def add_tag(self, tag, synonym=None, logo=None, description=None): pass @POST("cms/tags/%(tag)s") def post_tag(tag, logon=str, synonyms=str): pass #synonyms VS synonym @POST("cms/tags/%(tag)s/lock")
  • 16. 结论 •统⼀一 随时注意前后接口⼀一致 •抽象 隐藏不必要的细节 •充要 只接受充分且必须的参数 •直观 对人友好,对机器友好(调试) •原生 Pythonic
  • 18. Data Entry v1 a = (1, 2, 3)
  • 19. Data Entry v2 a = {“a”:1, “b”:2, “c”:3)
  • 20. Data Entry v3 class uDict(dict): def __getattr__(self, name): return self.__getitem__(name)
  • 21. Data Entry v4 class uDict(dict): def __getattr__(self, name, default=None): try: return self.__getitem__(name) except KeyError: return default a = uDict(a=1, b=2, c=3) print a.b print a.g
  • 22. Data Entry v5 class Entry(object): def __init__(self, a, b, c): self.a = a self.b = b self.c = c
  • 23. Data Entry v6 from collections import namedtuple Entry = namedtuple("Entry", "a b c") a = Entry(a=1, b=2, c=3)
  • 24. Data Entry v7 class Entry(namedtuple("Entry", "a b c")): def __new__(cls, a=None, b=None, c=None): return super(Entry, cls).__new__(cls, a, b, c)