• 利用 Python 做简单的代码生成


    在编写 C# 程序时,通常会有很多模式类似的代码,需要反复编写,这时候代码生成器就成了一个很有用的东西,可以大量降低人的重复劳动。

    原先我也看过 CodeSmith 等生成工具,但是要去学习它们的模板语言通常也需要时间成本,或者需要费一些气力才能达到自己想要的效果。
    另外,CodeDOM,Emit 等 C# 技术虽然有所研究,总感觉用来作这种事情实在是既累也不讨好,除了锻炼技术之外没别的好处。

    费话不多说,今天我写了两个简单的 python 程序来做这个事情,其中利用了 python 的带名称的格式化参数的特性,使得代码非常简单。

    集合类生成工具:

    #encoding=gb2312

    def make_collection_class(entity_name, entity_comment):
        template 
    = """
    using System.Collections;

    namespace SomeNameSpace.Model
    {
        /// <summary>
        /// %(entity_comment)s集合
        /// </summary>
        public class %(entity_name)sCollection : CollectionBase
        {
            public %(entity_name)sCollection()
            {
            }

            public void Add(%(entity_name)s obj)
            {
                base.InnerList.Add(obj);
            }

            public void Remove(%(entity_name)s obj)
            {
                base.InnerList.Remove(obj);
            }

            public %(entity_name)s this[int i]
            {
                get { return (%(entity_name)s) base.InnerList[i]; }
                set { base.InnerList[i] = value; }
            }
        }
    }
    """
        
    return template % locals()
        
    print make_collection_class('MyDocument''我的文档')    

    生成结果如下:

    using System.Collections;

    namespace SomeNameSpace.Model
    {
        
    /// <summary>
        
    /// 我的文档集合
        
    /// </summary>
        public class MyDocumentCollection : CollectionBase
        {
            
    public MyDocumentCollection()
            {
            }

            
    public void Add(MyDocument obj)
            {
                
    base.InnerList.Add(obj);
            }

            
    public void Remove(MyDocument obj)
            {
                
    base.InnerList.Remove(obj);
            }

            
    public MyDocument this[int i]
            {
                
    get { return (MyDocument) base.InnerList[i]; }
                
    set { base.InnerList[i] = value; }
            }
        }
    }

    再来一个实体类的生成代码:

    #encoding=gb2312

    def make_entity_class(class_name, class_name_comment, properties):
        property_template 
    = """
            %(type)s _%(property)s;
            
            public %(type)s %(property)s { get { return _%(property)s; } set { _%(property)s = value; }}
            
        
    """
        
        pstr 
    = "";
        
    for p in properties:        
            pstr 
    += property_template % ({
                
    "type": p[1],
                
    "property": p[0]
            })
                
        class_template 
    = """
    namespace SomeNameSpace.Model
    {
        /// <summary>
        /// %(class_name_comment)s
        /// </summary>
        public class %(class_name)s
        {
            %(pstr)s
        }
    }
    """
        
    return class_template % locals()


    print make_entity_class('Office''办公室', [
        [
    'OfficeId''int'], 
        [
    'OfficeName''string']
    ])

    生成的实体类如下:

    namespace SomeNameSpace.Model
    {
        
    /// <summary>
        
    /// 办公室
        
    /// </summary>
        public class Office
        {
            
            
    int _OfficeId;
            
            
    public int OfficeId { get { return _OfficeId; } set { _OfficeId = value; }}
            
        
            
    string _OfficeName;
            
            
    public string OfficeName { get { return _OfficeName; } set { _OfficeName = value; }}
            
        
        }
    }

    目前这两个代码的功能可以说非常简单,因为之前一直有想法用 python 做代码生成器,今天当做是一个起步吧:)
    下面的目标是要实现有 UI 的,能够读取分析模型文件,或者数据库 Schema 的工具。
  • 相关阅读:
    Golang 读写文件的操作
    初始 Elasticsearch
    数据存储单位的换算(bytes、KB MB GB TB PB EB ZB YB DB NB)
    Go 语言类型元信息的通用结构 _type
    空接口
    HashMap和Hashtable的区别
    谈谈final, finally, finalize的区别
    理解AOP
    Struts2 OGNL概述
    Struts2原理
  • 原文地址:https://www.cnblogs.com/RChen/p/423326.html
Copyright © 2020-2023  润新知