python删除属性_Python常量

本文介绍了Python中如何模拟实现常量,通过_const类防止常量被修改或删除。并展示了如何使用配置文件(如translator.properties)来存储常量,特别适用于项目的国际化配置。同时,文章讨论了常量的分类及其在实际项目中的应用,如默认值和特殊含义的数值。此外,还提及了防止常量被删除的方法。
摘要由CSDN通过智能技术生成

背景图来源:click

Bgwan:关于python读写文件那点事​zhuanlan.zhihu.com
a4c6249c983f9895bae3c6efa3e7f0c2.png

写在前面:

这篇文章主要介绍了Python中实现常量(Const)功能,python语言本身没有提供const,本文使用一个properties文件(类)来实现常量定义功能,并介绍了使用方法 同时作为livery1.2.x国际化的功能(AndroidLocalizePlugin不好用)的技术支持,感兴趣的的朋友可以参考下

与C/C++不同,Python在语法上并没有定义常量,尽管PEP 8定义了常量的命名规范为大写字母和下划线组成。

在实际项目中,经常会遇到需要使用const的情形,常量首次赋值后, 无法阻止其他代码对其进行修改或删除。

解决办法

这个问题也是从网上参考而来,在2001年就有人给出了解决方案Constants in Python,基本内容如下:

class _const:
    """常量数据类"""
    class ConstError(TypeError):
        """修改常量抛出此错误"""
        pass

    __PROPERTY_PATH = './translator.properties'

    def __setattr__(self, name, value):
        if self.__dict__.has_key(name):
            raise self.ConstError, "Can't rebind const instance attribute (%s)" % name

        self.__dict__[name] = value

import sys
sys.modules[__name__] = _const()

其大致含义为:

  • 通过_const的setattr对象方法判断该对象是否存在属性name,若存在则抛出自定义异常ConstError,否则创建该属性。
  • sys.modules[name] = const()这条语句,将_const实例化的对象赋值sys.modules[name],const模块被绑定成_const对象。name在首次载入const过程中为'const',而sys.modules是模块名与已加载模块的dict。

具体再解释一下sys.modules

This is a dictionary that maps module names to modules which have already been loaded. This can be manipulated to force reloading of modules and other tricks. Note that removing a module from this dictionary is not the same as calling reload() on the corresponding module object.

翻译过来: 使用sys.modules[name]可以获取一个模块对象,并可以通过该对象获取模块的属性(translator.properties中的配置内容),使用sys.modules向系统字典中注入了一个const对象从而实现在执行import const时实际获取了一个const实例的功能,即一个const实例,这样整个工程需要使用的常量都应该定义在一个文件中

,如本次需求的配置文件:translator.properties

SOURCE = zh_CHS
TARGET = EN
SOURCE_FILE_PATH = C:/Users/sun/public/python/res/strings/values-zh-rCN/strings.xml
TARGET_FILE_PATH = C:/Users/sun/public/python/res/strings/values/strings.xml
SAVE_FILE_PATH = C:/Users/sun/public/python/res/strings/sunst0069translated/strings.xml
TRANSLATION_RECORD_PATH = C:/Users/sun/public/python/sunst0069record/strings
TRANSLATION_RECORD_FILE = result.xlsx
EDITOR = sunst0069

如何使用const模块呢?(本次需求国际化livery需要将中文翻译为英文)**

import const
const.SOURCE = zh_CHS

若再次赋值const.SOURCE为英文,

const.SOURCE = en

则将抛出ConstError的异常。

如何避免常量被删除?

实际项目中,常量并不希望被其他代码删除。在_const类中加入:

def __delattr__(self, name):
    if self.__dict__.has_key(name):
        raise self.ConstError, "Can't unbind const const instance attribute (%s)" % name

    raise AttributeError, "const instance has no attribute '%s'" % name

如此,删除已定义的常量(假设const.SOURCE已经赋值):

del const.SOURCE 

则将抛出ConstError的异常。

配置文件与常量

实际项目中,为了让应用程序灵活部署,一般会用配置文件存储应用程序的各种参数;而这些参数通常都以常量语义存在于应用程序中。

在上述代码基础上,根据应用程序的实际情况将常量划分为3类:

  • 特殊含义的数值或字符串,如 ETC_FSTAB = “/etc/apt” 。其作用为
    (1).避免程序中到处出现类似特殊值,因为人为输入特殊值的低级错误将耗费不必要的调试/测试时间
    (2).另一方面, 神秘数值(magic number),如 LUN_BLOCK_SIZE = 6699,将影响程序的可读性。
  • 应用程序参数的默认值,如 URLOPEN_DEFAULT_TIMEOUT = 15 。其作用主要为配置文件参数的默认值。
  • 通过配置文件载入的参数,如通过ConfigParser.SafeConfigParser解析形如ini文件的参数。

第1和2类常量作为_const类的类属性,第3类常量可以在init方法中初始化。如:

class _const:
    ETC_FSTAB = "/etc/apt"
    LUN_BLOCK_SIZE = 6699
    URLOPEN_DEFAULT_TIMEOUT = 15

    def __init__(self):
        conf = ConfigParser.SafeConfigParser()
        conf.read(self.CONF_PATH)

        try:
            self.URLOPEN_TIMEOUT = conf.getint("DEFAULT", "urlopen_timeout")
        except:
            self.URLOPEN_TIMEOUT = self.URLOPEN_DEFAULT_TIMEOUT

    ... ...

某些情况下,应用程序可能并不希望const模块在被外部调用时绑定新属性(常量),实现如下:

def __init__(self):
    # Constant definition area

    _const.__setattr__ = _const._setattr_impl

def _setattr_impl(self, name, value):
    raise self.ConstError, "Can't bind const instance attribute (%s)" % name

其原理为_const对象初始化完成后将setattr设置为禁止绑定属性的实现。若在_const类中实现setattr为禁止绑定属性,则init也将无法初始化(绑定)对象属性。

总结

1.存在的小问题(该问题并不影响该解决方案的使用),具体请参考:

http://stackoverflow.com/questions/5365562/why-is-the-value-of-name-changing-after-assignment-to-sys-modules-name

2.常量和变量需要区分清楚,如果常量被修改,被删除都会抛出异常,如图:

7c2b1ba6a9611192848ded9906fb9f16.png

以上《Python常量》All

请尊重劳动成果,注意文中版权声明Android专栏不定时更新,欢迎点击关注我知乎。也可以同时关注人工智能专栏文艺语录专栏,本内容作者sunst0069,技术上有问题请沟通qyddai@gmail.com

作者:sunst 发布于: 2021-01-23 17:03 && 修改于:2021-01-23 17:24
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值