1

我正在阅读这个Genshi Tutorial并看到以下示例:

from formencode import Schema, validators

class LinkForm(Schema):
    username = validators.UnicodeString(not_empty=True)
    url = validators.URL(not_empty=True, add_http=True, check_exists=False)
    title = validators.UnicodeString(not_empty=True)

据我了解这个例子,我们创建了一个继承Schema类的新类,这个类包含三个方法:username, url, title。但是,我不确定最后一个,因为之前我只看到使用def.

无论如何,我的问题与此无关。我想知道是否可以使类的定义动态化。例如,有时我不想url或不想title上课。这似乎是可行的(我只是if在满足语句的情况下使用并为 url 分配一个值。

但是,如果我事先不知道我想在表单中包含哪些字段怎么办?例如,现在我有用户名、网址和标题。但是,如果以后我想拥有cityor怎么办age?我可以做这样的事情:

from formencode import Schema, validators

class LinkForm(Schema):

    __init__(self, fields):
          for field in fields:
               condition = fields[field]
               field = validators.UnicodeString(condition)

我认为这行不通。在这种情况下有解决办法吗?

4

3 回答 3

2

是的,您可以动态地将方法添加到实例中。不,你不能做你想做的事。

您可以将方法绑定到初始化程序中的实例。不幸的是,您所拥有的是描述符,这些描述符必须绑定到该类。

于 2013-07-22T05:40:26.807 回答
1

我会反过来——首先定义所有可能使用的表单字段,然后删除不需要的字段。

前提是您有:

from formencode import Schema, validators

class LinkForm(Schema):
    username = validators.UnicodeString(not_empty=True)
    url = validators.URL(not_empty=True, add_http=True, check_exists=False)
    title = validators.UnicodeString(not_empty=True)

你可以这样做:

def xy():
    my_form = LinkForm()
    del my_form.url
    …

… 或这个:

def xy():
    class CustomLinkForm(LinkForm):
        pass
    if …:
        del CustomLinkForm.url
    …

免责声明:我对 FormEncode 不熟悉,因此这可能取决于它的内部工作原理,这两个版本中的哪一个真正有效。

于 2013-07-22T05:49:36.997 回答
0

当然你可以有一个带有一些参数的构造函数,self如果你有这些参数,这些参数将是你的类的某些成员的值

__init__(self, fields):
          self.fields = []
          for field in fields:
               self.fields = self.fields + field 

在Dive into Python中看到这个

class FileInfo(UserDict):
    "store file metadata"               
    def __init__(self, filename=None): 
         UserDict.__init__(self)      
         self["name"] = filename 
  1. 类也可以(并且应该)有文档字符串,就像模块和函数一样。

  2. 在创建类的实例后立即调用init 。将其称为类的构造函数会很诱人但不正确。这很诱人,因为它看起来像构造函数(按照惯例,init是为类定义的第一个方法),行为像一个构造函数(它是在新创建的类实例中执行的第一段代码),甚至听起来像一个(“init”当然暗示了一种构造函数的性质)。不正确,因为在调用init时已经构造了对象,并且您已经拥有对类的新实例的有效引用。但是init是最接近 Python 中的构造函数的东西,它的作用几乎相同。

  3. 每个类方法的第一个参数,包括init,始终是对当前类实例的引用。按照惯例,这个参数总是命名为 self。在init方法中,self指的是新创建的对象;在其他类方法中,它指的是调用其方法的实例。虽然在定义方法时需要显式指定self,但在调用方法时不指定;Python 会自动为你添加它。

  4. init方法可以接受任意数量的参数,就像函数一样,参数可以用默认值定义,使它们对调用者是可选的。在这种情况下,filename 的默认值为 None,即 Python 空值。

请注意,在后面的示例中,您将学习如何处理继承类,调用__init()__这个继承类。

要回答关于类或实例变量的非问题,请参阅此

类定义中定义的变量是类变量;它们由所有实例共享。要创建实例变量,可以在 self.name = value 的方法中设置它们。类变量和实例变量都可以通过符号“self.name”访问,并且以这种方式访问​​时,实例变量会隐藏同名的类变量。类变量可以用作实例变量的默认值,但在那里使用可变值可能会导致意外结果。对于新型类,描述符可用于创建具有不同实现细节的实例变量。

于 2013-07-22T05:37:26.650 回答