首页 > 其他分享 >数据开发【配置文件】和【传参】规范

数据开发【配置文件】和【传参】规范

时间:2023-03-29 09:33:09浏览次数:42  
标签:传参 return 配置文件 self 规范 file properties def

概述

  • 配置文件
    概念:一种计算机文件,可给 计算机程序 配置 参数和初始设置
    场景:软件开发时,生产环境数据库账号密码 应写到配置文件,不应明文写到代码中
常见的配置文件后缀示例
.properties Kafka的server.properties
用于Java的日志配置文件log4j.properties
.xml Hadoop的core-site.xml
.ini MySQL的my.ini
.cnf MySQL的my.cnf
.conf Redis的redis.conf
.yml ElasticSearch的elasticsearch.yml
.bashrc 每个运行Bash用户的个性化设置
.json.config.js 前端常用

properties文件是Java中的一种配置文件,文件后缀为.properties,内容格式为key=value,用#注释

  • 传参
    本文的传参是指:通过 命令行 来给程序传递参数
    传参方式有:位置传参、键值对传参…
    当参数多于1个时,建议使用 键值对传参
    场景:日期、并行度

规范

  • 为了 数据开发 的 代码规范:
    配置格式 统一使用 properties
    传参方式 统一使用 键值对传参

  • 生产环境的配置文件 统一 存放到HDFS
    测试配置 写到 本地配置文件
    优先级(大者覆盖小者):
    临 时 配 置 > 生 产 配 置 临时配置 > 生产配置 临时配置>生产配置
    命 令 行 参 数 > H D F S 配 置 文 件 命令行参数 > HDFS配置文件 命令行参数>HDFS配置文件

  • 配置文件命名
    【建议】全小写
    【强制】下划线分隔单词
    示例:sqoop_mysql2hive.properties

  • 配置文件路径(两种方式):
    业务/子业务/存储媒介.properties
    部门/小组/岗位.properties

业务子业务媒介配置文件路径参数
金融 股票 MySQL /config/finance/stock/mysql.properties host
user
password
database
数据中台   HBase /config/data_center/hbase.properties zkUrl
数据中台   Kafka /config/data_center/kafka.properties bootstrap-server
部门小组员工ID配置文件路径参数
IT 大数据 实时计算 /config/it/big_data/rt.properties queue_name
IT 大数据 数据仓库 /config/it/big_data/dw.properties queue_name
IT 算法 自然语言处理 /config/it/ai/nlp.properties queue_name

代码模板

Python2

#!/usr/bin/python2
# coding:utf-8
"""
获取参数的工具类
    获取参数的方式
        1、properties配置文件
        2、命令行传参
    参数格式
        key=value
    命令行传参示例:
        python2 a.py ymd=2021-12-31 sql='带空格的value可用单引号包裹'
    参数优先级(大者覆盖小者)
        命令行参数 > HDFS配置文件 > 本地配置文件
        临时配置 > 生产配置 > 测试配置
详细链接:
    https://yellow520.blog.csdn.net/article/details/122088401
"""


class ParameterUtil:
    def __init__(self, hdfs_file='', local_file=''):
        self.dt = dict()
        if local_file:
            self._read_local_file(local_file)
        if hdfs_file:
            self._cat_hdfs(hdfs_file)
        self._get_cmd_parameters()

    def _read_local_file(self, file_path):
        """从本地读取配置文件,并获取参数"""
        try:
            with open(file_path) as f:
                self._properties2dict(f.read())
        except IOError:
            print('本地配置文件不存在')

    def _cat_hdfs(self, file_path):
        """从HDFS读取配置文件,并获取参数"""
        from subprocess import check_output, CalledProcessError
        cmd = 'hadoop fs -cat ' + file_path
        try:
            self._properties2dict(check_output(cmd, shell=True))
        except CalledProcessError:
            print('HDFS配置文件不存在')

    def _properties2dict(self, properties):
        """properties文件内容解析"""
        for r in properties.strip().split('\n'):
            if (not r.startswith('#')) and (r.find('=') > 0):
                k, v = r.split('=', 1)
                self.dt[k.strip()] = v.strip()

    def _get_cmd_parameters(self):
        """从命令行获取参数"""
        from sys import argv
        for a in argv[1:]:
            k, v = a.split('=', 1)
            self.dt[k.strip()] = v.strip()

    def get(self, key, default=None):
        """获取参数值"""
        return self.dt.get(key, default)

Python3

from time import time, strftime
from datetime import date, timedelta
import os
import platform
from subprocess import check_output, CalledProcessError


class Timer:
    def __init__(self):
        self.t = time()  # 起始秒数

    def __del__(self):
        if self.__str__():
            print('结束时间:%s' % self.now)
            print('运行时间:%s' % self)

    def __str__(self):
        t = self.seconds
        if t < 1:
            return ''
        elif t < 60:
            return '%.2fs' % t
        elif t < 3600:
            return '%.2fmin' % (t / 60)
        else:
            return '%.2fh' % (t / 3600)

    @property
    def seconds(self) -> float:
        """程序运行秒数"""
        return time() - self.t

    @property
    def now(self) -> str:
        """当前时间字符串"""
        return strftime('%Y-%m-%d %H:%M:%S')

    @property
    def today(self) -> date:
        return date.today()

    @property
    def yesterday(self) -> str:
        yesterday = self.today - timedelta(days=1)
        return yesterday.strftime('%Y-%m-%d')

    @property
    def this_year(self) -> int:
        return self.today.year

    @property
    def last_year(self) -> int:
        return self.this_year - 1

    @property
    def this_month(self) -> str:
        """本月,格式YYYY-MM"""
        return '%04d-%02d' % (self.this_year, self.today.month)

    @property
    def last_month(self) -> str:
        """上个月,格式YYYY-MM"""
        last_day_of_last_month = self.today - timedelta(days=self.today.day)  # 上个月的最后一天
        last_month = last_day_of_last_month.month  # 上个月
        year = last_day_of_last_month.year  # 上个月所在的年份
        ym = '%04d-%02d' % (year, last_month)  # 上个月的完整格式:YYYY-MM
        return ym


class Executor(Timer):
    def debug(self, text):
        """仅在Windows打印"""
        if platform.system() == 'Windows':
            print('[DEBUG {}] {}'.format(self.now, text))

    @staticmethod
    def execute(cmd):
        """执行Linux命令"""
        os.system(cmd)

    @staticmethod
    def evaluate(cmd):
        """执行Linux命令并获取返回值"""
        return check_output(cmd, shell=True)


class ParameterUtil(Executor):
    """https://yellow520.blog.csdn.net/article/details/122088401"""

    def __init__(self, *hdfs_files):
        super().__init__()
        self.dt = dict()
        for hdfs_file in hdfs_files:
            self._cat_hdfs(hdfs_file)
        self._get_cmd_parameters()

    def _cat_hdfs(self, file_path):
        """从HDFS读取配置文件,并获取参数"""
        cmd = 'hadoop fs -cat ' + file_path
        try:
            self._properties2dict(self.evaluate(cmd))
        except CalledProcessError:
            print('HDFS配置文件不存在')

    def read_local_file(self, file_path):
        """从本地读取配置文件,并获取参数"""
        try:
            with open(file_path) as f:
                self._properties2dict(f.read())
        except IOError:
            print('本地配置文件不存在')

    def _properties2dict(self, properties):
        """properties文件内容解析"""
        for r in properties.strip().split('\n'):
            if (not r.startswith('#')) and (r.find('=') > 0):
                k, v = r.split('=', 1)
                self.dt[k.strip()] = v.strip()

    def _get_cmd_parameters(self):
        """从命令行获取参数"""
        from sys import argv
        for a in argv[1:]:
            k, v = a.split('=', 1)
            self.dt[k.strip()] = v.strip()

    def get(self, key, default=None):
        """获取参数值"""
        return self.dt.get(key, default)

    @property
    def ymd(self) -> str:
        """获取日期,格式YYYY-MM-DD,默认昨天"""
        return self.get('ymd', self.yesterday)

    @property
    def ym(self) -> str:
        """获取日期,格式YYYY-MM,默认上个月"""
        return self.get('ym', self.last_month)

Java(待完善)

import java.io.FileInputStream;
import java.io.IOException;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Properties;

/**
 * ParameterUtil parameters = new ParameterUtil(args, "mysql.properties", "kafka.properties");
 * String ymd = parameters.get("ymd");
 */
public class ParameterUtil {
    Properties p = new Properties();

    public ParameterUtil(String[] args, String... hdfsPaths) {
        //获取HDFS上的配置文件
        for (String hdfsPath : hdfsPaths) {
            catHdfs(hdfsPath);
        }
        //命令行传参
        for (String arg : args) {
            String[] kv = arg.split("=", 1);
            p.setProperty(kv[0].trim(), kv[1].trim());
        }
    }

    /** 读取HDFS上的配置文件 */
    private void catHdfs(String hdfsPath) {
        try {
            Process process = Runtime.getRuntime().exec("hadoop fs cat " + hdfsPath);
            InputStream inputStream = process.getInputStream();
            BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
            String line;
            while ((line = reader.readLine()) != null) {
                if (!line.startsWith("#") && line.contains("=")) {
                    String[] kv = line.split("=", 1);
                    p.setProperty(kv[0].trim(), kv[1].trim());
                }
                System.out.println(line);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /** 读取本地properties配置文件 */
    public void readLocalFile(String localPath) {
        try {
            p.load(new FileInputStream(localPath));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public String get(String key) {
        return p.getProperty(key);
    }

    public String get(String key, String defaultValue) {
        return p.getProperty(key, defaultValue);
    }
}
 

 

标签:传参,return,配置文件,self,规范,file,properties,def
From: https://www.cnblogs.com/huanghanyu/p/17267565.html

相关文章

  • 移动端设计规范 - 文字使用规范
    这是一篇关于移动端产品界面设计时,文字大小的使用规范,前端人员如果能了解一点的话,在实际开发中和设计沟通时,节省沟通成本,也能提高设计落地开发时的还原度。关于在做移......
  • IDC机房设计规范
    互联网数据中心(IDC)从规划建设、运行维护到经营管理都是一项复杂的系统工程,涉及多个行业,众多子系统和专业。传统数据中心能源消耗量大,能源利用效率低。因此,绿色数据中心(Green......
  • 配置文件 条件查询
    编写接口方法:Mapper**参数:所有查询条件**结果:List<Brand>2.编写SQL语句:SQL映射文件3.执行方法,测试方法一:步骤一:在BrandMapp......
  • 模块化:AMD规范
    模块化:AMD规范是席木木啊已于2022-10-0222:11:59修改421收藏分类专栏:Vue文章标签:AMD模块化javascript版权Vue专栏收录该内容41篇文章2订阅订阅专栏......
  • 今日共同报告-13-app底部导航栏的实现,fragment传参
    今日共同报告-13今天时间比较充沛,学了许多东西,主要是fragment传参,同时把底部导航栏完成了。目前进度的页面展示:能够实现点击切换和选中的选项颜色变化  部分代码:......
  • C++命名规范
    C++命名规范共用准则只能是字母(A-Z,a-z)、数字(0-9)和下划线(_)组成,区分大小写文件、函数、类、变量名应当具有描述性类、自定义类型和变量名应当使用名词,函数名使用......
  • 传参base64时的+号变空格问题
    原创:扣钉日记(微信公众号ID:codelogs),欢迎分享,非公众号转载保留此声明。问题发生上上周,看到一位老哥找我们组同事联调接口,不知道是什么问题,两人坐一起搞了快1个小时,看起来......
  • 解决微信小程序传参字符过长的问题
    1:使用wx.navigateTo 进行页面跳转传参传入:wx.navigateTo({url:'/page/testPage/testPage/',success:function(res){res.eventChannel.emit('getParam......
  • Winform中通过自带的App.config实现从配置文件中读取配置
    场景Winform中实现保存配置到文件/项目启动时从文件中读取配置(序列化与反序列化对象):Winform中实现保存配置到文件/项目启动时从文件中读取配置(序列化与反序列化对象)_win......
  • 配置文件完成增删改查一
    准备环境数据库表tb_brand 实体类Brand 测试用例    ps.在了test文件下安装MyBatisX插件。MyBatisX是一款基于IDEA的快速开......