python中每个子类中类变量的不同值

2024-04-25 13:47:31 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个永远不会被实例化的基类。这个基类有不同的子类。每个子类定义了某些类变量,在这些变量中,所有子类的名称相同,但值将不同。例如

class Base:
    def display(self): 
        print self.logfile, self.loglevel
class d1(Base):
    logfile = "d1.log"
    loglevel = "debug"
    def temp(self):
        Base.display(self)
class d2(Base):
    logfile = "d2.log"
    loglevel = "info"
    def temp(self):
        Base.display(self)

如果明天定义了任何新的子类,那么实现子类的人应该为这些类变量提供一些值,而不要错过定义它们的正确方法是什么?在


Tags: 实例selflogbase定义defdisplay基类
3条回答

一种不需要实例化类以进行检查的方法是创建一个元类:

class BaseAttrEnforcer(type):
    def __init__(cls, name, bases, d):
        if 'loglevel' not in d:
            raise ValueError("Class %s doesn't define loglevel attribute" % name)
        type.__init__(cls, name, bases, d)

class Base(object):
    __metaclass__ = BaseAttrEnforcer
    loglevel = None

class d1(Base):
    logfile = "d1.log"
    loglevel = "debug"

class d2(Base):
    logfile = "d2.log"
    loglevel = "info"

class d3(Base):
    logfile = "d3.log"
    # I should fail

这应该行得通

>>> class Base(object):
...  def __init__(self):
...   if not hasattr(self, "logfile"):
...    raise Exception("not implemented")
... 
>>> class d1(Base):
...  logfile='logfile1.log'
... 
>>> class d2(Base):
...  pass
... 
>>> d1()
<__main__.d1 object at 0x7d0d0>
>>> d2()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 4, in __init__
not implemented

您可以按照ciphor的建议,通过简单地签入构造函数来实现这一点,但是您也可以使用abc.抽象属性基类中的decorator,以确保定义与所需属性类似的属性。在

然后,解释器会检查实例化实例时是否创建了日志文件:

import abc
#It is almost always a good idea to have your base class inherit from object
class Base(object):  
    __metaclass__ = abc.ABCMeta
    @abc.abstractproperty
    def logfile(self):
        raise RuntimeError("This should never happen")

class Nice(Base):
    @property
    def logfile(self):
        return "actual_file.log"

class Naughty(Base):
    pass

d=Nice()  #This is fine
print d.logfile  #Prints actual_file.log
d=Naughty()  #This raises an error: 
#TypeError: Can't instantiate abstract class Base with abstract methods logfile

看到了吗 http://docs.python.org/library/abc.html 可能更有用: http://www.doughellmann.com/PyMOTW/abc/ 更多细节。在

还有一个注意-当你的子类调用基本显示(self)在你最初的例子中,让他们打电话会更有意义自我展示(). 方法是从基类继承的,这种方法避免了对基类进行硬编码。如果有更多的子类,那么继承链也会变得更干净。在

相关问题 更多 >