代码之家  ›  专栏  ›  技术社区  ›  bearplane

类方法输入变量

  •  0
  • bearplane  · 技术社区  · 7 年前

    通常,当我用Python(和其他语言)创建类时,我很难决定哪种做法更好:(a)在方法函数中使用实例变量,或者(b)在函数定义中列出输入变量。

        class ClassA(object):
            def __init__(self, a):
                self.variable_a = a
    
            def square_a(self):
                return self.variable_a ** 2
    

    (b)

       class ClassB(object):
            def __init__(self, b):
                self.variable_b = b
    
            def square_b(self, input_var):
                return input_var ** 2
    

    这些例子非常简单和明显,但突出了我感到困惑的地方,关于哪个是更好的想法。此外,是否禁止在外部设置实例变量 __init__ 方法?例如:

       class ClassC(object):
            def __init__(self, c):
                self.variable_c = c
    
            def square_c(self):
                self.square_of_c = self.variable_c ** 2
    

    :我理解这个问题有点模糊,但我问这个问题是因为很难知道人们希望在我为协作项目编写的源代码中看到什么。如果我给出的一个或多个例子是反模式的,我的想法是这个问题将为我提供有用的见解。

    政治公众人物20:

    There should be one-- and preferably only one --obvious way to do it.

    2 回复  |  直到 7 年前
        1
  •  1
  •   0x5453 Yuki    7 年前

    在本例中,(b)作为成员函数不是很有用。它可以很容易地成为一个自由函数:

    def square(input_var):
        return input_var ** 2
    

    这可以说是一个更好的接口,因为它可以在任何上下文中使用,而不仅仅是从 ClassB .

    如果我知道的话,通常我会同意 self.variable_a 是函数应该需要的唯一输入。如果我想让它处理任何东西,并且它不依赖于类中的任何东西,我会让它成为一个自由函数。如果我不想让它和任何东西一起工作 依赖于某个类状态,然后使其成为将输入作为参数的成员。例如,如果 ClassA variable_a variable_b square_a 修改 变量b

    此外,是否禁止在外部设置实例变量

    不,但通常最好确保在类实例化时在某个地方初始化所有成员。即使您只是将您的成员初始化为 None . 检查成员变量是否为 没有一个 而不是试图确定它是否被定义。

    编辑:另外几个例子:

    # Here a free function makes the most sense because the operation is 'pure'
    # i.e. it has no side effects and requires no state besides its input arguments
    def square(value):
        return value ** 2
    
    class LoggedCalculator(object):
        def __init__(self, logger):
            self.__logger = logger
    
        # (a) makes more sense here because it depends on class state and doesn't need to change
        # its behavior by taking in some parameter
        def get_logger(self):
            return self.__logger
    
        # (b) makes more sense here because we rely on a mixture of class state and some other input
        def square(self, value):
            result = square(value) # Re-use free function above
            self.__logger.info('{}^2 = {}'.format(value, result))
            return result
    
    calc = LoggedCalculator(logging.getLogger())
    calc.square(4)  # This requires an instance of LoggedCalculator
    square(2)       # This can be called anywhere, even if you don't have a logger available
    
        2
  •  0
  •   ColdBrew    7 年前

    你的问题很模糊,因此很难回答。所有类似乎都有正确的语法。

    但是b)对我来说比a)更有用


    你也可以考虑制作方舟A。 static method ,因为它不使用任何对象属性(从不打电话 self

    class ClassB(object):
        def __init__(self, b):
            self.variable_b = b
    
        @staticmethod
        def square_b(input_var):
            return input_var ** 2
    

    变体c)在语法方面也是有效的,但有些人可能认为这是一种糟糕的做法。这确实是一个品味问题,但许多书籍和网站都会建议您在 初始化