类实例上的delattr产生意外的AttributeError [英] delattr on class instance produces unexpected AttributeError

查看:195
本文介绍了类实例上的delattr产生意外的AttributeError的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我具有以下用于配置实现的抽象基类(简称):

I have the following abstract base class for configuration implementation (cut short):

class Config():
    """
    Configuration file binding
    """   
    def __init__(self, path):
        """
        Initialize the config file
        """
        path = path if path.endswith(self.__SUFFIX) else path + self.__SUFFIX
        self.__file = ConfigFile(path)
        self.__defaults = self.dict()

    @property    
    def fields(self):
        """
        Returns a list of fields
        """
        return [field for field in self.dict()]

    def dict(self):
        """
        Determine existing fields
        """
        return {field:getattr(self, field) 
                for field in dir(self) 
                if field.upper() == field 
                and not field.startswith('_')}

    def reset(self):
        """
        Reset the file to the default values
        """
        self.__clear()
        return self.__load(self.__defaults)

    def __load(self, d):
        """
        Load data from file
        """
        for field in d:
            if field.upper() == field:
                setattr(self, field, self.__decode(d[field]))

    def __clear(self):
        """
        Remove all fields
        """
        print('My fields: ', end='')    # XXX: Debug
        print(self.fields)  # XXX: Debug
        print('My attributes: ', end='')    # XXX: Debug
        print(dir(self))    # XXX: Debug
        for field in self.fields:
            print('Removing field: ' + field)
            delattr(self, field)

    <SNIP>

这正在我程序的系统级配置中实现:

This is being implemented by my program's system-wide configuration:

class __Sysconfig(Config):
    """
    H.O.M.I.E.'s system configuration
    """
    ### Application information ###
    APP_NAME = 'H.O.M.I.E.'
    APP_VER = '0.1-indev'
    APP_FULL_NAME = "Cool system"

    ### System logging ###
    LOG_DIR = '/var/log/homie.d'
    LOGFILE = '/var/log/homie'
    LOGLVL = 2

    ### System files ###
    DAEMON_SERVICES_FILE = '/var/run/homie.services'
    DAEMON_SOCK = 'tcp://127.0.0.1'
    GLOBAL_CONFIG_DIR = '/usr/local/etc/homie.d'

    ### System EMail ###
    EMAIL_FROM = 'homie@company.com'
    TECH_EMAIL = 'me@company.com'
    ADMIN_EMAILS = ['me@company.com', 'other@company.com']

    def __init__(self):
        """
        Creates a sysconfig instance
        """
        super().__init__('/usr/local/etc/homie')

然后通过以下方式初始化:

Which then is initialized by:

sysconfig = __Sysconfig()
sysconfig.reset()

但是,这会产生以下错误(使用Config()的打印输出进行调试):

This, however, produces the following error (With printouts from Config() for debugging):

My fields: ['EMAIL_FROM', 'APP_VER', 'LOG_DIR', 'GLOBAL_CONFIG_DIR', 'TECH_EMAIL', 'DAEMON_SERVICES_FILE', 'ADMIN_EMAILS', 'APP_NAME', 'LOGFILE', 'APP_FULL_NAME', 'DAEMON_SOCK', 'LOGLVL']
My attributes: ['ADMIN_EMAILS', 'APP_FULL_NAME', 'APP_NAME', 'APP_VER', 'DAEMON_SERVICES_FILE', 'DAEMON_SOCK', 'EMAIL_FROM', 'GLOBAL_CONFIG_DIR', 'LOGFILE', 'LOGLVL', 'LOG_DIR', 'TECH_EMAIL', '_Config__SUFFIX', '_Config__TYPES', '_Config__clear', '_Config__decode', '_Config__defaults', '_Config__encode', '_Config__file', '_Config__lbi', '_Config__lei', '_Config__load', '_Config__ls', '_Config__ts', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'dict', 'exists', 'fields', 'lbi', 'lei', 'load', 'loaded', 'ls', 'reload', 'remove', 'reset', 'store', 'ts']
Removing field: EMAIL_FROM
Traceback (most recent call last):
  File "/etc/init.d/retard", line 3, in <module>
    from homie.init import __main__
  File "/usr/lib/python3.4/site-packages/homie/init/__main__.py", line 20, in <module>
    from ..api import Customer, Service
  File "/usr/lib/python3.4/site-packages/homie/api/__init__.py", line 12, in <module>
    from .abc import CAC
  File "/usr/lib/python3.4/site-packages/homie/api/abc.py", line 14, in <module>
    from ..homie import sysconfig
  File "/usr/lib/python3.4/site-packages/homie/homie.py", line 50, in <module>
    sysconfig.reset()
  File "/usr/lib/python3.4/site-packages/homie/lib/config.py", line 114, in reset
    self.__clear()
  File "/usr/lib/python3.4/site-packages/homie/lib/config.py", line 159, in __clear
    delattr(self, field)
AttributeError: EMAIL_FROM

为什么delattr()找不到属性?

Why does delattr() does not find the attribute?

推荐答案

在定义子类__Sysconfig(Config)时,python显然会将属性绑定到该类.实例self可以访问它们,但不能删除它们.

When defining the subclass __Sysconfig(Config), python obviously binds the attributes to the class. The instance self can access them, but not delete them.

delattr(self, field)更改为delattr(self.__class__, field)可以达到目的!

Changing delattr(self, field) to delattr(self.__class__, field) did the trick!

这篇关于类实例上的delattr产生意外的AttributeError的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆