Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

为自身定义copy方法 #1

Open
aixcyi opened this issue Aug 7, 2023 · 0 comments
Open

为自身定义copy方法 #1

aixcyi opened this issue Aug 7, 2023 · 0 comments
Labels
Python 3 一种最初多用于科研的弱类型脚本语言

Comments

@aixcyi
Copy link
Owner

aixcyi commented Aug 7, 2023

  一些类自带了copy()或者作用类似于浅拷贝的方法,比如内置的listdict、decimal的Decimal等等。

  copy()指的是复制一个数据相同但地址不同的对象,类似于用相同数据调用构造方法。因此在定制类的时候,如果不借助Python自带的copy库,可以在类体内调用自身的构造方法达到相同目的。

直接调用

class DateRange:
    def __init__(self, start, stop):
        self._start = start
        self._stop = stop
        if not start < stop:
            raise ValueError("开始日期必须早于结束日期")

    def copy(self):
        return DateRange(self._start, self._stop)

  因为类内的方法是动态加载的,因此在Python中,方法内可以直接使用类名而不会被警告“名称未定义”。

  这种办法的好处就是输入快,而且易读性很强;但缺点是如果类被继承了,且子类没有重写copy方法,会导致返回父类,而不是当前的子类。因此可以——

间接调用

class DateRange:
    def __init__(self, start, stop):
        self._start = start
        self._stop = stop
        if not start < stop:
            raise ValueError("开始日期必须早于结束日期")

    def copy(self):
        return type(self)(self._start, self._stop)

  与直接调用的唯一区别是:将DateRange()改成了type(self)()

  实际上,DateRange是一个“类”对象(而不是实例化后的那个对象),它的类型就是type,而type(self)得到的正是这个对象,故而DateRange()等价于type(self)()

  当然,其也等价于被@classmethod注解后的第一个方法参数——cls

类方法调用

class DateRange:
    def __init__(self, start, stop):
        self._start = start
        self._stop = stop
        if not start < stop:
            raise ValueError("开始日期必须早于结束日期")

    @classmethod
    def operate(cls, start, stop):
        return cls(start, stop)

  有些情况下,可能需要在类方法中调用自身的构造方法。此时,最方便也最保险的做法是直接使用cls()构造自身。因为cls本身会随着子类继承而改变,也无需再用type()转换,就能得到当前“类”对象。

@aixcyi aixcyi added the Python 3 一种最初多用于科研的弱类型脚本语言 label Aug 7, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Python 3 一种最初多用于科研的弱类型脚本语言
Projects
None yet
Development

No branches or pull requests

1 participant