在Python中是否可以根据构造函数的输入创建一组类的方法?

时间:2013-07-22 05:27:17

标签: python class oop methods

我正在阅读此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类的新类,该类包含三个方法:usernameurltitle。但是,我不确定最后一个因为之前我只看到用def创建的方法。

无论如何,我的问题与此无关。我想知道是否可以使类的定义动态化。例如,有时我不希望urltitle在班级中。它似乎是可行的(我只使用if并仅在满足-statement时为url分配值。

但是,如果我事先不知道我希望在表格中有哪些字段呢?例如,现在我有用户名,网址和标题。但是如果以后我希望cityage怎么办?我能做那样的事吗:

from formencode import Schema, validators

class LinkForm(Schema):

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

我认为它不起作用。在这种情况下有解决方法吗?

3 个答案:

答案 0 :(得分:2)

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

您可以将方法绑定到初始化程序中的实例。不幸的是,你拥有descriptors并且那些必须绑定到该类。

答案 1 :(得分: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,因此它可能取决于其内部工作原理这两个版本实际上有哪些。

答案 2 :(得分: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. 类也可以(也应该)拥有doc字符串,就像模块和   功能。

  2.   在实例之后立即调用
  3. init   类已创建。这称之为诱人但不正确   类的构造函数。它很诱人,因为它看起来像一个   构造函数(按照惯例, init 是为其定义的第一个方法   这个类似于一个(它是第一个在一个代码中执行的代码)   新创建的类的实例),甚至听起来像一个(“init”   当然暗示了构造者的本性。不正确,因为   对象已经在 init 被调用时构建,   并且您已经拥有对该新实例的有效引用   类。但是 init 是你最接近的一个   Python中的构造函数,它填充了相同的角色。

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

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

  8.   

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

回答关于类或实例变量的非问题,see this

  

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