在Point class in Geopy中,我们可以看到很多不同的方法来调用它的构造函数:
>>> p1 = Point(41.5, -81, 0)
>>> p2 = Point(latitude=41.5, longitude=-81)
>>> p3 = Point([41.5, -81, 0])
>>> p4 = Point((41.5, -81))
>>> p5 = Point(p4)
>>> p6 = Point('41.5,-81.0')
>>> p7 = Point('41.5 N -81.0 W')
>>> p8 = Point('-41.5 S, 81.0 E, 2.5km')
>>> p9 = Point('23 26m 22s N 23 27m 30s E 21.0mi')
>>> p10 = Point('''3 26' 22" N 23 27' 30" E''')
我想知道这是好的还是坏的做法,代码味道,如果它违反了一些pythonic成语。实际上这个问题适用于任何OO语言,但我特别询问python
答案 0 :(得分:4)
def __init__(self, *args, **kwargs):
# "args" holds a list of positional arguments,
# "kwargs" holds a dictionary of keyword arguments
if len(args) == 1 and not kwargs:
if isinstance(args[0], str):
if re.match(args[0], some_regex):
... # etc
这使初始化代码变得非常糟糕,并且很难将数据安全地传递给构造函数,并使构造函数意外地处理格式错误的数据。
在我看来,它违反了Python的Zen(import this
)上的子弹1,2,3,5,7,10,12和17。所以我会说它违反了Pythonic的习语。
<子> •美丽胜过丑陋。 •明确比隐含更好。 •简单比复杂更好。 •Flat优于嵌套。 •可读性计数。 •错误不应该默默地传递。 •面对模棱两可,拒绝猜测的诱惑。 •如果实施难以解释,那么这是一个坏主意。 子>
查看链接代码,我看到了
POINT_PATTERN = re.compile(r"""
.*?
(?P<latitude>
(?P<latitude_direction_front>[NS])?[ ]*
(?P<latitude_degrees>-?%(FLOAT)s)(?:[%(DEGREE)sD\*\u00B0\s][ ]*
(?:(?P<latitude_arcminutes>%(FLOAT)s)[%(PRIME)s'm][ ]*)?
(?:(?P<latitude_arcseconds>%(FLOAT)s)[%(DOUBLE_PRIME)s"s][ ]*)?
)?(?P<latitude_direction_back>[NS])?)
%(SEP)s
(?P<longitude>
(?P<longitude_direction_front>[EW])?[ ]*
(?P<longitude_degrees>-?%(FLOAT)s)(?:[%(DEGREE)sD\*\u00B0\s][ ]*
(?:(?P<longitude_arcminutes>%(FLOAT)s)[%(PRIME)s'm][ ]*)?
(?:(?P<longitude_arcseconds>%(FLOAT)s)[%(DOUBLE_PRIME)s"s][ ]*)?
)?(?P<longitude_direction_back>[EW])?)(?:
%(SEP)s
(?P<altitude>
(?P<altitude_distance>-?%(FLOAT)s)[ ]*
(?P<altitude_units>km|m|mi|ft|nm|nmi)))?
.*?$
""" % {
"FLOAT": r'\d+(?:\.\d+)?',
"DEGREE": format.DEGREE,
"PRIME": format.PRIME,
"DOUBLE_PRIME": format.DOUBLE_PRIME,
"SEP": r'\s*[,;/\s]\s*',
}, re.X)
就个人而言,我印象深刻。要让那个大小的正则表达式如此可读并不容易。但这很难解释或简单。
您可以使用staticmethod
或classmethod
构造函数。
class Rectangle:
def __init__(self, a=0, b=0):
self.a = a # measured in meters
self.b = b # measured in meters
@classmethod
def as_square(cls, a):
return cls(a, a)
@classmethod
def from_inches(cls, a_inches, b_inches):
inch = 0.0254 # in meters
return cls(a_inches * inch, b_inches * inch)
def __repr__(self):
templ = "<Rectangle: {self.a:.3f} x {self.b:.3f}>"
return templ.format(self=self)
这允许您从数据中实例化,同时仍然保持不同的方法。
>>> Rectangle(10, 20)
<Rectangle: 10.000 x 20.000>
>>> Rectangle.as_square(100)
<Rectangle: 100.000 x 100.000>
>>> Rectangle.from_inches(2, 4)
<Rectangle: 0.051 x 0.102>
您是否看到了int
可以解析的内容?
from decimal import Decimal
int(2546)
#>>> 134
int(17657.342)
#>>> 17657
int(Decimal("134"))
#>>> 2546
int("5443")
#>>> 5443
int("543", 34)
#>>> 5919
int("໖᭗")
#>>> 67
说出我喜欢的内容,我不会说服很多人没有这方面的先例。