进行复杂初始化的pythonic方法是什么

时间:2018-07-13 15:49:33

标签: python python-3.x oop initialization

假设我有一个Point类:

class Point:
    def __init__(self, x, y):
        self.x = x
        self.y = y

假设我总是使用x_y形式的字符串创建Points:

x, y = my_string.split('_')
p = Point(x, y)

由于我总是使用字符串来创建Point p。以这种方式更改__init__是否可以:

class Point:
    def __init__(self, s):
        x, y = s.split('_')
        self.x = x
        self.y = y

__init__应该只接受设置属性的值,还是可以做更多的事情?

1 个答案:

答案 0 :(得分:1)

__init__函数可以采用对您的应用程序有意义的任何参数。如果您的Point类被其他人使用,他们可能想知道为什么他们只能通过提供格式化的字符串来实例化该类。您可以使用以下静态方法来允许两种初始化方式:

class Point:
    def __init__(self, x, y):
        self.x = x
        self.y = y

    @classmethod
    def from_string(cls, s):
        x, y = s.split('_')
        return cls(x, y)

# example usage
p1 = Point(10, 20)
p2 = Point.from_string("15_25")

编辑:

正如Patrick在评论中所指出的那样,与我最初使用classmethod相比,优先使用staticmethod

编辑2:

如果您使用的是Python 3.7,则可以为此使用dataclass

In [1]: from dataclasses import dataclass

In [4]: @dataclass
   ...: class Point:
   ...:     x: int
   ...:     y: int
   ...:     
   ...:     @classmethod
   ...:     def from_string(cls, s):
   ...:         return cls(*s.split("_"))
   ...:

In [5]: Point(1, 2)
Out[5]: Point(x=1, y=2)

In [6]: Point(1, "2")
Out[6]: Point(x=1, y='2')

In [7]: Point.from_string("3_4")
Out[7]: Point(x='3', y='4')

但是要小心你的类型。如上面的代码所示,没有自动将类型转换为int