"일반 메서드"란 무엇인가요?
다른 유형에 대해 동일한 작업을 구현하는 여러 메서드로 구성된 메서드입니다.
예를 들어
이제 다음과 같은 방법으로 사용자 정의 날짜 클래스(CustomDate
)를 생성해야 하는 요구 사항이 있습니다. CustomDate
):
时间戳
年、月、日(包含三个整数的元组)
ISO 格式的字符串
Datetime
类
一般实现
from datetime import date, datetime class CustomDate: def __init__(self, arg): if isinstance(arg, (int, float)): self.__date = date.fromtimestamp(arg) elif isinstance(arg, tuple) and len(arg) == 3 and all(map(lambda x: isinstance(x, int), arg): self.__date = date(*arg) elif isinstance(arg, str): self.__date = date.fromisoformat(arg) elif isinstance(arg, datetime): self.__date = datetime.date() else: raise TypeError("could not create instance from " + type(arg).__name__) @property def date(): return self.__date
注:这里暂不讨论传入的日期/时间戳合不合法,仅仅只对类型做大致判断。
有没有更好的方式?
我们可以将不同的构建方式拆分为多个方法,并利用 functools
中的 singledispatchmethod
装饰器来根据传入的参数类型决定调用哪个方法。
from datetime import date, datetime from functools import singledispatchmethod class CustomDate: @singledispatchmethod def __init__(self, arg): raise TypeError("could not create instance from " + type(arg).__name__) @__init__.register(int) @__init__.register(float) def __from_timestamp(self, arg): self.__date = date.fromtimestamp(arg) @__init__.register(tuple) def __from_tuple(self, arg): if len(arg) == 3 and all(map(lambda x: isinstance(x, int), arg)): self.__date = date(*arg) else: raise ValueError("could not create instance from a malformed tuple") @__init__.register(str) def __from_isoformat(self, arg): self.__date = date.fromisoformat(arg) @__init__.register(datetime) def __from_datetime(self, arg): self.__date = arg.date() @property def date(self): return self.__date
这样一来,我们便能将每种参数类型的初始化独立成一个个的方法了。
缺点
#1 单分派
在调用期间应该使用哪个方法实现由分派算法决定。如果该算法只基于单个参数的类型来决定使用哪个方法实现,则称其为单分派。
singledispatchmethod
就是就是单分派的。也就是说,只有第一个参数会作为考量。这在实际业务中是远远不足的。
#2 不支持 typing
然而,如上,对元组中元素类型判断还是需要我们用 if
/else
实现。也就是说,我们不能使用 typing.Tuple[int, int, int]
。
作为一种折中的方案,或许我们可以定义一个 ThreeIntTuple
类来对其进行限定,将这些判断从 CustomDate
类中隔离开来。
这里仅提供一个思路让大家参考,我就不实现了(因为我们有更好的方式 xD)。
替代方案:multimethod 库
这个库不是标准库之一,需要通过 pip 安装:
pip install multimethod
优势
multimethod
采用的是多分派算法,能更好地满足更复杂的场景。此外,该库对 typing
中的类型也有不错的支持。
更更好的实践方式
回到上面的问题,我们可以这么改进:
使用
multimethod
方法来替代singledispatchmethod
;使用
Tuple[int, int, int]
来替代tuple
,不再需要手动校验元组的长度和元素类型了;
from datetime import date, datetime from typing import Tuple, Union from multimethod import multimethod class CustomDate: @multimethod def __init__(self, arg): raise TypeError("could not create instance from " + type(arg).__name__) @__init__.register def __from_timestamp(self, arg: Union[int, float]): self.__date = date.fromtimestamp(arg) @__init__.register def __from_tuple(self, arg: Tuple[int, int, int]): self.__date = date(*arg) @__init__.register def __from_isoformat(self, arg: str): self.__date = date.fromisoformat(arg) @__init__.register def __from_datetime(self, arg: datetime): self.__date = arg.date() @property def date(self): return self.__date
究极好的实践方式(真正的方法重载)
在此之前,先问大家一个简单的问题(这跟我们之后的内容有很大的联系):
class A: def a(self): print(1) def a(self): print(2) A().a()
以上这段代码会输出什么?还是会抛出错误?
输出 2
。
在 Python 中,如果定义了重名的方法,最后一个方法是会覆盖掉之前的方法的。
但你或许不知,我们可以通过元类(metaclass)来改变这一行为:
class MetaA(type): class __prepare__(dict): def __init__(*args): pass def __setitem__(self, key, value): if self.get('a'): # Line 7 super().__setitem__('b', value) # Line 8 else: super().__setitem__(key, value) class A(metaclass=MetaA): def a(self): print(1) def a(self): print(2) A().a() # => 1 A().b() # => 2 # Line 22
在第 7 和第 8 行,我们将重名的 a
方法改名为 b
,并在第 22 行成功地调用它了。
multimethod
的维护者们很好地运用了这一点,对重名的方法进行了处理,以达到一种“特殊的效果”。
回到正题,我们可以做出如下改进:
将
multimethod.multidata
设置为CustomDate
类的元类;-
将所有方法命名为
__init__
- Timestamp
년, 월, 일(3개의 정수를 포함하는 튜플)
🎜Datetime
클래스의 일반 구현 🎜🎜 🎜🎜🎜from datetime import date, datetime from typing import Tuple, Union from multimethod import multimeta class CustomDate(metaclass=multimeta): def __init__(self, arg: Union[int, float]): self.__date = date.fromtimestamp(arg) def __init__(self, arg: Tuple[int, int, int]): self.__date = date(*arg) def __init__(self, arg: str): self.__date = date.fromisoformat(arg) def __init__(self, arg: datetime): self.__date = arg.date() def __init__(self, arg): raise TypeError("could not create instance from " + type(arg).__name__) @property def date(self): return self.__date🎜 참고: 들어오는 날짜/시간 스탬프가 합법적인지 여부에 대해서는 논의하지 않으며 유형에 대해서만 대략적인 판단을 내립니다. 🎜🎜더 좋은 방법이 있나요? 🎜🎜다양한 빌드 방법을 여러 메서드로 분할하고
functools
의 singledispatchmethod
데코레이터를 사용하여 전달된 매개변수 유형에 따라 호출할 메서드를 결정할 수 있습니다. 🎜rrreee🎜이런 방식으로 각 매개변수 유형의 초기화를 별도의 메소드로 분리할 수 있습니다. 🎜🎜단점🎜#1 단일 디스패치
🎜호출 중에 사용해야 하는 메소드 구현은 디스패치 알고리즘에 따라 결정됩니다. 알고리즘이 단일 매개변수의 유형만을 기반으로 사용할 메소드 구현을 결정하는 경우 이를 단일 디스패치라고 합니다. 🎜🎜singledispatchmethod
는 단일 디스패치입니다. 즉, 첫 번째 매개변수만 고려됩니다. 이는 실제 비즈니스에서는 충분하지 않습니다. 🎜#2는 입력을 지원하지 않습니다
🎜그러나 위에서 언급한 것처럼 요소 유형을 결정하려면if
/else
를 사용해야 합니다. 튜플. 즉, typing.Tuple[int, int, int]
를 사용할 수 없습니다. 🎜🎜절충안으로 ThreeIntTuple
클래스를 정의하여 이를 제한하고 이러한 판단을 CustomDate
클래스에서 분리할 수 있습니다. 🎜🎜여기에는 참고용 아이디어일 뿐이며 구현하지는 않겠습니다(더 나은 방법이 있기 때문입니다). 🎜🎜대안: 멀티메소드 라이브러리🎜🎜이 라이브러리는 표준 라이브러리 중 하나가 아니며 pip를 통해 설치해야 합니다. 🎜rrreee🎜Advantages🎜🎜멀티메서드
는 다중 디스패치 알고리즘을 사용하므로 더 나은 요구 사항을 충족할 수 있습니다. 더 복잡한 요구 사항 장면. 또한 라이브러리는 입력
의 유형을 잘 지원합니다. 🎜🎜더 나은 연습🎜🎜위의 질문으로 돌아가서 다음과 같이 개선할 수 있습니다.🎜- 🎜대신
다중 메서드
메서드를 사용하세요. >singledispatchmethod; 🎜🎜 - 🎜
Tuple
을 대체하려면Tuple[int, int, int]
를 사용하세요. 더 이상 튜플을 수동으로 확인할 필요가 없습니다. )의 요소 유형: 🎜rrreee🎜위 코드는 무엇을 출력합니까? 아니면 오류가 발생할까요? 🎜🎜2
를 출력하세요. 🎜🎜Python에서는 동일한 이름의 메소드가 정의되면 마지막 메소드가 이전 메소드를 덮어씁니다. 🎜🎜하지만 메타클래스를 통해 이 동작을 변경할 수 있다는 사실을 모르실 수도 있습니다. 🎜rrreee🎜 7행과 8행에서는 동일한 이름의a
메서드 이름을b
로 바꿉니다. 22번 라인에서 성공적으로 호출합니다. 🎜🎜다중 메서드
의 관리자는 이를 잘 활용하여 "특수 효과"를 달성하기 위해 중복된 이름을 가진 메서드를 처리했습니다. 🎜🎜주제로 돌아가서 다음과 같은 개선 사항을 적용할 수 있습니다. 🎜- 🎜
multimethod.multidata
를CustomDate
로 설정 > 클래스의 메타클래스입니다. 🎜🎜 - 🎜모든 메소드 이름을
__init__
로 지정합니다. 🎜🎜🎜rrreee🎜효과적으로 보면 이는 정적 언어 메서드 오버로딩과 정확히 같습니다! 🎜
- 🎜
위 내용은 Python 클래스에서 여러 생성자 메서드 오버로드 및 일반 메서드를 정의하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

Tomergelistsinpython, youcanusethe operator, extendmethod, listcomprehension, oritertools.chain, 각각은 각각의 지위를 불러 일으킨다

Python 3에서는 다양한 방법을 통해 두 개의 목록을 연결할 수 있습니다. 1) 작은 목록에 적합하지만 큰 목록에는 비효율적입니다. 2) 메모리 효율이 높지만 원래 목록을 수정하는 큰 목록에 적합한 확장 방법을 사용합니다. 3) 원래 목록을 수정하지 않고 여러 목록을 병합하는 데 적합한 * 운영자 사용; 4) 메모리 효율이 높은 대형 데이터 세트에 적합한 itertools.chain을 사용하십시오.

join () 메소드를 사용하는 것은 Python의 목록에서 문자열을 연결하는 가장 효율적인 방법입니다. 1) join () 메소드를 사용하여 효율적이고 읽기 쉽습니다. 2)주기는 큰 목록에 비효율적으로 운영자를 사용합니다. 3) List Comprehension과 Join ()의 조합은 변환이 필요한 시나리오에 적합합니다. 4) READE () 방법은 다른 유형의 감소에 적합하지만 문자열 연결에 비효율적입니다. 완전한 문장은 끝납니다.

pythonexecutionissprocessoftransformingpythoncodeintoExecutableInstructions.1) the -interreadsTheCode, ConvertingItintoByTecode, thethepythonVirtualMachine (pvm)을 실행합니다

Python의 주요 특징은 다음과 같습니다. 1. 구문은 간결하고 이해하기 쉽고 초보자에게 적합합니다. 2. 개발 속도 향상, 동적 유형 시스템; 3. 여러 작업을 지원하는 풍부한 표준 라이브러리; 4. 광범위한 지원을 제공하는 강력한 지역 사회와 생태계; 5. 스크립팅 및 빠른 프로토 타이핑에 적합한 해석; 6. 다양한 프로그래밍 스타일에 적합한 다중-파라 디그 지원.

Python은 해석 된 언어이지만 편집 프로세스도 포함됩니다. 1) 파이썬 코드는 먼저 바이트 코드로 컴파일됩니다. 2) 바이트 코드는 Python Virtual Machine에 의해 해석되고 실행됩니다. 3)이 하이브리드 메커니즘은 파이썬이 유연하고 효율적이지만 완전히 편집 된 언어만큼 빠르지는 않습니다.

USEAFORLOOPHENTERATINGOVERASERASERASPECIFICNUMBEROFTIMES; USEAWHILLOOPWHENTINUTIMONDITINISMET.FORLOOPSAREIDEALFORKNOWNSEDINGENCENCENS, WHILEWHILELOOPSSUITSITUATIONS WITHERMINGEDERITERATIONS.

Pythonloopscanleadtoerrors likeinfiniteloops, modifyinglistsdizeration, off-by-by-byerrors, zero-indexingissues, andnestedloopineficiencies.toavoidthese : 1) aing'i


핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

Video Face Swap
완전히 무료인 AI 얼굴 교환 도구를 사용하여 모든 비디오의 얼굴을 쉽게 바꾸세요!

인기 기사

뜨거운 도구

에디트플러스 중국어 크랙 버전
작은 크기, 구문 강조, 코드 프롬프트 기능을 지원하지 않음

SublimeText3 영어 버전
권장 사항: Win 버전, 코드 프롬프트 지원!

맨티스BT
Mantis는 제품 결함 추적을 돕기 위해 설계된 배포하기 쉬운 웹 기반 결함 추적 도구입니다. PHP, MySQL 및 웹 서버가 필요합니다. 데모 및 호스팅 서비스를 확인해 보세요.

SublimeText3 Linux 새 버전
SublimeText3 Linux 최신 버전

SecList
SecLists는 최고의 보안 테스터의 동반자입니다. 보안 평가 시 자주 사용되는 다양한 유형의 목록을 한 곳에 모아 놓은 것입니다. SecLists는 보안 테스터에게 필요할 수 있는 모든 목록을 편리하게 제공하여 보안 테스트를 더욱 효율적이고 생산적으로 만드는 데 도움이 됩니다. 목록 유형에는 사용자 이름, 비밀번호, URL, 퍼징 페이로드, 민감한 데이터 패턴, 웹 셸 등이 포함됩니다. 테스터는 이 저장소를 새로운 테스트 시스템으로 간단히 가져올 수 있으며 필요한 모든 유형의 목록에 액세스할 수 있습니다.