gpt4 book ai didi

做组合别名的 Pythonic 方式

转载 作者:行者123 更新时间:2023-12-03 16:54:52 33 4
gpt4 key购买 nike

做组合别名的最pythonic和正确的方法是什么?

这是一个假设的场景:

class House:
def cleanup(self, arg1, arg2, kwarg1=False):
# do something

class Person:
def __init__(self, house):
self.house = house
# aliases house.cleanup
# 1.
self.cleanup_house = self.house.cleanup

# 2.
def cleanup_house(self, arg1, arg2, kwarg1=False):
return self.house.cleanup(arg1=arg1, arg2=arg2, kwarg1=kwarg1)


AFAIK with #1 我测试过的编辑理解这些和 #2 一样好 - 自动完成、文档字符串等。

#1方法有什么缺点吗?从 python 的角度来看,哪种方式更正确?

要扩展方法 #1 不可设置和类型提示的变体,将不受评论中指出的所有问题的影响:
class House:

def cleanup(self, arg1, arg2, kwarg1=False):
"""clean house is nice to live in!"""
pass


class Person:
def __init__(self, house: House):
self._house = house
# aliases
self.cleanup_house = self.house.cleanup

@property
def house(self):
return self._house

最佳答案

第一种方法有很多问题:

  • 当它引用的属性发生变化时,别名不会更新,除非您跳过额外的环节。例如,您可以制作 house一个 property使用二传手,但对于不应该需要它的东西来说,这是不平凡的工作。有关示例实现,请参阅此答案的结尾。
  • cleanup_house不会被继承。类中定义的函数对象是非数据描述符,可以被继承和覆盖,也可以绑定(bind)到实例。类中根本不存在第一种方法中的实例属性。它是一个绑定(bind)方法的事实是偶然的。子类将无法访问 super().cleanup_house ,举个具体的例子。
  • person.cleanup_house.__name__ != 'cleanup_house' .这不是您经常检查的内容,但是当您这样做时,您会期望函数名称为 cleanup .

  • 好消息是您不必多次重复签名即可使用方法 #2。 Python 提供了非常方便的 splat ( * )/splatty-splat ( ** ) 表示法,用于将所有参数检查委托(delegate)给被包装的方法:
    def cleanup_house(self, *args, **kwargs):
    return self.house.cleanup(*args, **kwargs)

    就是这样。所有常规和默认参数都按原样传递。

    这就是#2 是迄今为止更 Pythonic 的方法的原因。我不知道它将如何与支持类型提示的编辑器交互,除非您复制方法签名。

    可能有问题的一件事是 cleanup_house.__doc__house.cleanup.__doc__ 不一样.这可能值得转换 houseproperty ,其 setter 分配 cleanup_house.__doc__ .

    要解决问题 1.(但不是 2. 或 3.),您可以实现 house作为带有 setter 的属性。这个想法是每当 house 更新别名。属性变化。一般来说,这不是一个好主意,但这是您在问题中所拥有的替代实现,它可能会更好地工作:
    class House:
    def cleanup(self, arg1, arg2, kwarg1=False):
    """clean house is nice to live in!"""
    pass


    class Person:
    def __init__(self, house: House):
    self.house = house # use the property here

    @property
    def house(self):
    return self._house

    @house.setter
    def house(self, value):
    self._house = house
    self.cleanup_house = self._house.cleanup

    关于做组合别名的 Pythonic 方式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60584948/

    33 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com