Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/lua/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在Python中自引用类?_Python - Fatal编程技术网

如何在Python中自引用类?

如何在Python中自引用类?,python,Python,我希望这个模板类接受自身的子类和其他类型的子类,这些子类在self中具有类型(I)。\u允许\u类型 class Template(): _allowed_types = [str, Template, SafeHtml] 上面的代码抛出以下内容: NameError: name 'Template' is not defined 在定义类后添加类: class Template(): _allowed_types = [str, SafeHtml] Template._a

我希望这个模板类接受自身的子类和其他类型的子类,这些子类在self中具有
类型(I)。\u允许\u类型

class Template():
    _allowed_types = [str, Template, SafeHtml]
上面的代码抛出以下内容:

NameError: name 'Template' is not defined

在定义类后添加类:

class Template():
    _allowed_types = [str, SafeHtml]

Template._allowed_types.append(Template)
根据需要,在创建类对象之前运行类主体,因此尚未定义名称
Template
。但是,在创建对象之后,您始终可以更改类属性。

另一种(也许是更干净的)方法是声明一个中间类:

class BasicTemplate():
    pass

class Template(BasicTemplate):
    _allowed_types = [str, BasicTemplate]
BasicTemplate
可以是完全虚拟的,也可以包含一些有用的代码。拥有一个不允许包含自身的模板在某个时候可能会派上用场


当然,这需要
isinstance
而不是
type()
来检查类型,但无论如何这是个好主意。

另一个选项是使用属性来延迟字段

class Test(object):
    @property
    def allowed(self):
        return [str, Test]

t = Test()
print Test in t.allowed

很好地展示了“另一种方式”,但是IMHO不是“更干净的”——这会弄脏类层次结构,迫使一个没有的层次结构——如果已经有了一个层次结构,可能会通过创建中间类或具有多重继承的第二个层次结构而使事情变得更糟:正如您所看到的,它很快变得丑陋。简单地允许使用类名的字符串,并检查从相关模块检索字符串和名称要简单得多,就像Django所做的那样。@jsbueno:是的,这是主观的,在没有看到整个画面的情况下谈论是毫无意义的。在我的书中,课外摆弄私人成员是一个很大的禁忌,对于字符串标识符也是如此。我不明白为什么否决票也是如此——这当然是一个很好的方式——只有在少数情况下不应该被优先选择