μΉ΄ν…Œκ³ λ¦¬ 보관물: Python

Python

믹슀 μΈμ΄λž€ 무엇이며 μ™œ μœ μš©ν•©λ‹ˆκΉŒ? 달리 클래슀λ₯Ό ν™•μž₯ν•˜κΈ° μœ„ν•΄ 닀쀑 상속을 μ‚¬μš©ν•˜λŠ”

” Programming Python β€œμ—μ„œ Mark LutzλŠ” β€œmixins”λ₯Ό μ–ΈκΈ‰ν•©λ‹ˆλ‹€. λ‚˜λŠ” C / C ++ / C # λ°°κ²½μ—μ„œ μ™”μœΌλ©° 이전 μš©μ–΄λ₯Ό λ“£μ§€ λͺ»ν–ˆμŠ΅λ‹ˆλ‹€. 믹슀 μΈμ΄λž€ λ¬΄μ—‡μž…λ‹ˆκΉŒ?

이 예제 의 ν–‰ 사이λ₯Ό 읽으면 (맀우 κΈΈκΈ° λ•Œλ¬Έμ— μ—°κ²°λ˜μ–΄ 있음), β€˜μƒλ‹Ήν•œβ€™ν•˜μœ„ ν΄λž˜μŠ€μ™€ 달리 클래슀λ₯Ό ν™•μž₯ν•˜κΈ° μœ„ν•΄ 닀쀑 상속을 μ‚¬μš©ν•˜λŠ” 경우라고 κ°€μ •ν•©λ‹ˆλ‹€. 이게 μ˜³μ€ κ±°λ‹ˆ?

μƒˆλ‘œμš΄ κΈ°λŠ₯을 μ„œλΈŒ ν΄λž˜μŠ€μ— λ„£λŠ” λŒ€μ‹  μ™œ κ·Έλ ‡κ²Œν•˜κ³  μ‹ΆμŠ΅λ‹ˆκΉŒ? κ·Έ μ μ—μ„œ μ™œ 믹슀 인 / λ©€ν‹° 상속 방법이 μ»΄ν¬μ§€μ…˜μ„ μ‚¬μš©ν•˜λŠ” 것보닀 λ‚«μŠ΅λ‹ˆκΉŒ?

믹슀 인과 닀쀑 상속을 λΆ„λ¦¬ν•˜λŠ” 것은 λ¬΄μ—‡μž…λ‹ˆκΉŒ? 의미둠의 문제 일까?



λ‹΅λ³€

믹슀 인은 νŠΉλ³„ν•œ μ’…λ₯˜μ˜ 닀쀑 μƒμ†μž…λ‹ˆλ‹€. 믹슀 인이 μ‚¬μš©λ˜λŠ” 두 κ°€μ§€ μ£Όμš” 상황이 μžˆμŠ΅λ‹ˆλ‹€.

  1. μˆ˜μ—…μ— λ§Žμ€ μ˜΅μ…˜ κΈ°λŠ₯을 μ œκ³΅ν•˜λ €κ³ ν•©λ‹ˆλ‹€.
  2. λ§Žμ€ λ‹€λ₯Έ ν΄λž˜μŠ€μ—μ„œ ν•˜λ‚˜μ˜ νŠΉμ • κΈ°λŠ₯을 μ‚¬μš©ν•˜λ €κ³ ν•©λ‹ˆλ‹€.

첫 번째 μ˜ˆλŠ” werkzeug의 μš”μ²­ 및 응닡 μ‹œμŠ€ν…œμ„ κ³ λ € ν•˜μ‹­μ‹œμ˜€ . λ‹€μŒκ³Ό 같이 λ§ν•˜λ©΄ 였래된 μš”μ²­ 객체λ₯Ό λ§Œλ“€ 수 μžˆμŠ΅λ‹ˆλ‹€.

from werkzeug import BaseRequest

class Request(BaseRequest):
    pass

수락 헀더 지원을 μΆ”κ°€ν•˜λ €λ©΄

from werkzeug import BaseRequest, AcceptMixin

class Request(AcceptMixin, BaseRequest):
    pass

헀더, etags, 인증 및 μ‚¬μš©μž μ—μ΄μ „νŠΈ 지원을 μ§€μ›ν•˜λŠ” μš”μ²­ 였브젝트λ₯Ό μž‘μ„±ν•˜λ €λ©΄ λ‹€μŒμ„ μˆ˜ν–‰ν•˜μ‹­μ‹œμ˜€.

from werkzeug import BaseRequest, AcceptMixin, ETagRequestMixin, UserAgentMixin, AuthenticationMixin

class Request(AcceptMixin, ETagRequestMixin, UserAgentMixin, AuthenticationMixin, BaseRequest):
    pass

차이점은 λ―Έλ¬˜ν•˜μ§€λ§Œ μœ„μ˜ μ˜ˆμ—μ„œ 믹슀 인 ν΄λž˜μŠ€λŠ” λ…μžμ μœΌλ‘œ λ§Œλ“€μ–΄μ§€μ§€ μ•Šμ•˜μŠ΅λ‹ˆλ‹€. 보닀 전톡적인 닀쀑 μƒμ†μ—μ„œ AuthenticationMixin(예λ₯Ό λ“€μ–΄)λŠ” μ•„λ§ˆλ„ 더 λΉ„μŠ·ν•  것 Authenticatorμž…λ‹ˆλ‹€. 즉, μˆ˜μ—…μ€ μ•„λ§ˆλ„ λ…μžμ μœΌλ‘œ μ„€ 수 μžˆλ„λ‘ μ„€κ³„λ˜μ—ˆμ„ κ²ƒμž…λ‹ˆλ‹€.


λ‹΅λ³€

λ¨Όμ € 믹슀 인은 닀쀑 상속 μ–Έμ–΄λ‘œλ§Œ μ‘΄μž¬ν•©λ‹ˆλ‹€. Java λ˜λŠ” C #μ—μ„œλŠ” 믹슀 인을 μˆ˜ν–‰ ν•  수 μ—†μŠ΅λ‹ˆλ‹€.

기본적으둜 믹슀 인은 ν•˜μœ„ ν΄λž˜μŠ€μ— λŒ€ν•΄ μ œν•œλœ κΈ°λŠ₯κ³Ό λ‹€ν˜•μ„± 곡λͺ…을 μ œκ³΅ν•˜λŠ” λ…λ¦½ν˜• κΈ°λ³Έ μœ ν˜•μž…λ‹ˆλ‹€. C #으둜 μƒκ°ν•˜κ³  μžˆλ‹€λ©΄ 이미 κ΅¬ν˜„ λ˜μ—ˆκΈ° λ•Œλ¬Έμ— μ‹€μ œλ‘œ κ΅¬ν˜„ν•  ν•„μš”κ°€μ—†λŠ” μΈν„°νŽ˜μ΄μŠ€λ₯Ό μƒκ°ν•΄λ³΄μ‹­μ‹œμ˜€. 당신은 κ·Έκ²ƒμ—μ„œ μƒμ†ν•˜κ³  κ·Έ κΈ°λŠ₯μœΌλ‘œλΆ€ν„° 이읡을 μ–»μŠ΅λ‹ˆλ‹€.

믹슀 인은 일반적으둜 λ²”μœ„κ°€ 쒁으며 ν™•μž₯λ˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.

[νŽΈμ§‘-μ΄μœ μ— κ΄€ν•΄μ„œ :]

당신이 μš”μ²­ν•œ 이후 μ™œ κ·ΈλŸ°μ§€ μ„€λͺ…ν•΄μ•Όν•œλ‹€κ³  μƒκ°ν•©λ‹ˆλ‹€. κ°€μž₯ 큰 μž₯점은 λ°˜λ³΅ν•΄μ„œ 슀슀둜 ν•  ν•„μš”κ°€ μ—†λ‹€λŠ” κ²ƒμž…λ‹ˆλ‹€. C #μ—μ„œ 믹슀 인이 ν˜œνƒμ„ 얻을 μˆ˜μžˆλŠ” κ°€μž₯ 큰 μž₯μ†ŒλŠ” Disposal νŒ¨ν„΄ 일 수 μžˆμŠ΅λ‹ˆλ‹€ . IDisposable을 κ΅¬ν˜„ν•  λ•Œλ§ˆλ‹€ 거의 항상 λ™μΌν•œ νŒ¨ν„΄μ„ λ”°λ₯΄κ³  μ‹Άμ§€λ§Œ μ•½κ°„μ˜ λ³€ν˜•μœΌλ‘œ λ™μΌν•œ κΈ°λ³Έ μ½”λ“œλ₯Ό μž‘μ„±ν•˜κ³  λ‹€μ‹œ μž‘μ„±ν•˜κ²Œλ©λ‹ˆλ‹€. ν™•μž₯ κ°€λŠ₯ν•œ 폐기 믹슀 인이 μžˆλ‹€λ©΄ μΆ”κ°€ 타이핑을 많이 쀄일 수 μžˆμŠ΅λ‹ˆλ‹€.

[νŽΈμ§‘ 2-λ‹€λ₯Έ μ§ˆλ¬Έμ— λŒ€λ‹΅ν•˜κΈ° μœ„ν•΄]

믹슀 인과 닀쀑 상속을 λΆ„λ¦¬ν•˜λŠ” 것은 λ¬΄μ—‡μž…λ‹ˆκΉŒ? 의미둠의 문제 일까?

예. 믹슀 인과 ν‘œμ€€ 닀쀑 μƒμ†μ˜ 차이점은 의미둠의 문제 μΌλΏμž…λ‹ˆλ‹€. 닀쀑 μƒμ†μ΄μžˆλŠ” ν΄λž˜μŠ€λŠ” 닀쀑 μƒμ†μ˜ μΌλΆ€λ‘œ 믹슀 인을 ν™œμš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

믹슀 인의 μš”μ μ€ 상속 μœ ν˜•μ— 영ν–₯을주지 μ•ŠμœΌλ©΄ μ„œ 상속을 톡해 λ‹€λ₯Έ μœ ν˜•μ— β€œν˜Όν•©β€λ  μˆ˜μžˆλŠ” μœ ν˜•μ„ μƒμ„±ν•˜λŠ” λ™μ‹œμ— ν•΄λ‹Ή μœ ν˜•μ— μœ μš©ν•œ κΈ°λŠ₯을 μ œκ³΅ν•˜λŠ” κ²ƒμž…λ‹ˆλ‹€.

λ‹€μ‹œ ν•œ 번 이미 κ΅¬ν˜„ 된 μΈν„°νŽ˜μ΄μŠ€λ₯Ό μƒκ°ν•΄λ³΄μ‹­μ‹œμ˜€.

λ‚˜λŠ” 개인적으둜 믹슀 인을 μ§€μ›ν•˜μ§€ μ•ŠλŠ” μ–Έμ–΄λ‘œ κ°œλ°œν•˜κΈ° λ•Œλ¬Έμ— 개인적으둜 믹슀 인을 μ‚¬μš©ν•˜μ§€ μ•ŠκΈ° λ•Œλ¬Έμ— β€œahah”λ₯Ό μ œκ³΅ν•˜λŠ” ν›Œλ₯­ν•œ 예λ₯Ό μƒκ°ν•΄λ‚΄λŠ” 데 정말 μ–΄λ €μš΄ μ‹œκ°„μ„ 보내고 μžˆμŠ΅λ‹ˆλ‹€. λ‹Ήμ‹ μ„μœ„ν•œ μˆœκ°„. ν•˜μ§€λ§Œ λ‹€μ‹œ μ‹œλ„ν•˜κ² μŠ΅λ‹ˆλ‹€. λ‚˜λŠ” λŒ€λΆ€λΆ„μ˜ μ–Έμ–΄κ°€ 이미 μ–΄λ–€ 방식 μœΌλ‘œλ“  κ·Έ κΈ°λŠ₯을 μ œκ³΅ν•˜λŠ” κ²ƒμœΌλ‘œ κ³ μ•ˆλœ 예제λ₯Ό μ‚¬μš©ν•  κ²ƒμž…λ‹ˆλ‹€. κ·ΈλŸ¬λ‚˜ 믹슀 인이 μ–΄λ–»κ²Œ λ§Œλ“€μ–΄μ§€κ³  μ‚¬μš©λ˜λŠ”μ§€λ₯Ό μ„€λͺ… ν•  κ²ƒμž…λ‹ˆλ‹€. κ°„λ‹€ :

XML둜 μ§λ ¬ν™”ν•˜κ±°λ‚˜ XMLμ—μ„œ 직렬화 ν•  μˆ˜μžˆλŠ” μœ ν˜•μ΄ μžˆλ‹€κ³  κ°€μ •ν•˜μ‹­μ‹œμ˜€. ν˜•μ‹μ— ν˜•μ‹μ˜ 데이터 κ°’μ΄μžˆλŠ” XML 쑰각이 포함 된 λ¬Έμžμ—΄μ„ λ°˜ν™˜ν•˜λŠ” β€œToXMLβ€λ©”μ„œλ“œμ™€ ν˜•μ‹μ΄ λ¬Έμžμ—΄μ˜ XML μ‘°κ°μ—μ„œ 데이터 값을 μž¬κ΅¬μ„± ν•  μˆ˜μžˆλŠ” β€œFromXMLβ€ν˜•μ‹μ„ μ œκ³΅ν•˜λ €κ³ ν•©λ‹ˆλ‹€. λ‹€μ‹œ ν•œ 번, 이것은 κ³ μ•ˆλœ μ˜ˆμ΄λ―€λ‘œ μ•„λ§ˆλ„ μ–Έμ–΄μ˜ λŸ°νƒ€μž„ λΌμ΄λΈŒλŸ¬λ¦¬μ—μ„œ 파일 슀트림 λ˜λŠ” XML Writer 클래슀λ₯Ό μ‚¬μš©ν•  κ²ƒμž…λ‹ˆλ‹€. μš”μ μ€ 객체λ₯Ό XML둜 μ§λ ¬ν™”ν•˜κ³  XMLμ—μ„œ μƒˆ 객체λ₯Ό κ°€μ Έμ˜€κ³  μ‹Άλ‹€λŠ” κ²ƒμž…λ‹ˆλ‹€.

이 μ˜ˆμ œμ—μ„œ λ‹€λ₯Έ μ€‘μš”ν•œ 점은 일반적인 λ°©λ²•μœΌλ‘œμ΄ μž‘μ—…μ„ μˆ˜ν–‰ν•œλ‹€λŠ” κ²ƒμž…λ‹ˆλ‹€. μ§λ ¬ν™”ν•˜λ €λŠ” λͺ¨λ“  μœ ν˜•μ— λŒ€ν•΄ β€œToXML”및 β€œFromXMLβ€λ©”μ†Œλ“œλ₯Ό κ΅¬ν˜„ν•  ν•„μš”κ°€ μ—†μœΌλ©°, μœ ν˜•μ΄μ΄λ₯Ό μˆ˜ν–‰ν•˜κ³  μž‘λ™ν•˜λ„λ‘ν•˜λŠ” 일반적인 μˆ˜λ‹¨μ„ μ›ν•©λ‹ˆλ‹€. μ½”λ“œ μž¬μ‚¬μš©μ„ μ›ν•©λ‹ˆλ‹€.

μ–Έμ–΄κ°€ μ§€μ›ν•˜λŠ” 경우 XmlSerializable 믹슀 인을 λ§Œλ“€μ–΄μ„œ μž‘μ—…μ„ μˆ˜ν–‰ ν•  수 μžˆμŠ΅λ‹ˆλ‹€. 이 μœ ν˜•μ€ ToXML 및 FromXML λ©”μ†Œλ“œλ₯Ό κ΅¬ν˜„ν•©λ‹ˆλ‹€. μ˜ˆμ œμ— μ€‘μš”ν•˜μ§€ μ•Šμ€ λ©”μ»€λ‹ˆμ¦˜μ„ μ‚¬μš©ν•˜λ©΄ ToXML이 λ°˜ν™˜ ν•œ XML 쑰각을 μž‘μ„±ν•˜κΈ° μœ„ν•΄ ν˜Όν•© 된 λͺ¨λ“  μœ ν˜•μ—μ„œ ν•„μš”ν•œ λͺ¨λ“  데이터λ₯Ό μˆ˜μ§‘ ν•  수 있으며 FromXML이 μ „ν™”ν–ˆλ‹€.

그리고 그게 λ‹€μ•Ό. 이λ₯Ό μ‚¬μš©ν•˜λ €λ©΄ XmlSerializableμ—μ„œ 상속 된 XML둜 serializeν•΄μ•Όν•˜λŠ” λͺ¨λ“  μœ ν˜•μ΄ μžˆμŠ΅λ‹ˆλ‹€. ν•΄λ‹Ή μœ ν˜•μ„ 직렬화 λ˜λŠ” μ—­ 직렬화해야 ν•  λ•Œλ§ˆλ‹€ ToXML λ˜λŠ” FromXML을 ν˜ΈμΆœν•˜λ©΄λ©λ‹ˆλ‹€. μ‹€μ œλ‘œ XmlSerializable은 본격적인 μœ ν˜•μ΄λ©° λ‹€ν˜•μ„±μ΄κΈ° λ•Œλ¬Έμ— 원본 μœ ν˜•μ— λŒ€ν•΄ μ „ν˜€ λͺ¨λ₯΄λŠ” XmlSerializable μœ ν˜•μ˜ λ°°μ—΄ 만 λ°›μ•„λ“€μ΄λŠ” λ¬Έμ„œ μ‹œλ¦¬μ–Ό 라이저λ₯Ό μž‘μ„±ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

이제이 μ‹œλ‚˜λ¦¬μ˜€λ₯Ό μ‚¬μš©ν•˜μ—¬ λ―ΉμŠ€μ—μ„œ λͺ¨λ“  클래슀λ₯Ό ν˜Όν•©ν•˜λŠ” λͺ¨λ“  클래슀 λ˜λŠ”μ΄λ₯Ό ν˜Όν•©ν•˜λŠ” μœ ν˜•μ— νŠΈλžœμž­μ…˜ 성을 μ œκ³΅ν•˜λŠ” 믹슀 인을 μž‘μ„±ν•˜λŠ” 믹슀 인 μž‘μ„±κ³Ό 같은 λ‹€λ₯Έ 상황에 λŒ€ν•΄μ΄ μ‹œλ‚˜λ¦¬μ˜€λ₯Ό μ‚¬μš©ν•œλ‹€κ³  μƒμƒν•΄λ³΄μ‹­μ‹œμ˜€.

믹슀 인을 λ‹€λ₯Έ μœ ν˜•μ— 영ν–₯을주지 μ•Šκ³  μœ ν˜•μ— μ†ŒλŸ‰μ˜ κΈ°λŠ₯을 μΆ”κ°€ν•˜λ„λ‘ μ„€κ³„λœ μž‘μ€ κΈ°λ³Έ μœ ν˜•μœΌλ‘œ μƒκ°ν•˜λ©΄ ν™©κΈˆμƒ‰μž…λ‹ˆλ‹€.

잘만되면 πŸ™‚


λ‹΅λ³€

이 닡변은 λ‹€μŒ κ³Ό 같은 μ˜ˆμ œμ™€ 믹슀 인을 μ„€λͺ…ν•˜λŠ” 것을 λͺ©ν‘œλ‘œν•©λ‹ˆλ‹€ .

  • 자체 포함 : μ§§κ³  예제λ₯Ό μ΄ν•΄ν•˜κΈ° μœ„ν•΄ 라이브러리λ₯Ό μ•Œ ν•„μš”κ°€ μ—†μŠ΅λ‹ˆλ‹€.

  • λ‹€λ₯Έ μ–Έμ–΄κ°€ μ•„λ‹Œ Python .

    Ruby와 같은 λ‹€λ₯Έ μ–Έμ–΄μ˜ μ˜ˆμ œκ°€ μžˆλ‹€λŠ” 것이 이해할 λ§Œν•©λ‹ˆλ‹€. μ™œλƒν•˜λ©΄ μš©μ–΄λŠ” ν•΄λ‹Ή μ–Έμ–΄μ—μ„œ 훨씬 μΌλ°˜μ μ΄μ§€λ§Œ 파이썬 μŠ€λ ˆλ“œμž…λ‹ˆλ‹€.

λ˜ν•œ λ…Όλž€μ˜ μ—¬μ§€κ°€μžˆλŠ” μ§ˆλ¬Έμ„ κ³ λ €ν•΄μ•Όν•œλ‹€.

믹슀 인을 νŠΉμ„±ν™”ν•˜κΈ° μœ„ν•΄ 닀쀑 상속이 ν•„μš”ν•©λ‹ˆκΉŒ?

μ •μ˜

νŒŒμ΄μ¬μ—μ„œ 믹슀 인이 무엇인지 λͺ…ν™•ν•˜κ²Œ λ§ν•˜λŠ” β€œκΆŒν•œμžˆλŠ”β€μΆœμ²˜μ˜ μΈμš©μ„ 아직 보지 λͺ»ν–ˆμŠ΅λ‹ˆλ‹€.

믹슀 인에 λŒ€ν•œ 두 κ°€μ§€ κ°€λŠ₯ν•œ μ •μ˜λ₯Ό λ³΄μ•˜μœΌλ©° (좔상적 인 κΈ°λ³Έ ν΄λž˜μŠ€μ™€ 같은 λ‹€λ₯Έ μœ μ‚¬ν•œ κ°œλ…κ³Ό λ‹€λ₯Έ κ²ƒμœΌλ‘œ κ°„μ£Όλ˜λŠ” 경우) μ‚¬λžŒλ“€μ€ μ–΄λŠ 것이 μ˜¬λ°”λ₯Έμ§€μ— μ „μ μœΌλ‘œ λ™μ˜ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.

ν•©μ˜λŠ” μ–Έμ–΄λ§ˆλ‹€ λ‹€λ₯Ό 수 μžˆμŠ΅λ‹ˆλ‹€.

μ •μ˜ 1 : 닀쀑 상속 μ—†μŒ

믹슀 인은 클래슀의 일뢀 λ©”μ†Œλ“œκ°€ ν΄λž˜μŠ€μ— μ •μ˜λ˜μ§€ μ•Šμ€ λ©”μ†Œλ“œλ₯Ό μ‚¬μš©ν•˜λ„λ‘ ν΄λž˜μŠ€μž…λ‹ˆλ‹€.

λ”°λΌμ„œμ΄ ν΄λž˜μŠ€λŠ” μΈμŠ€ν„΄μŠ€ν™”κ°€ μ•„λ‹ˆλΌ κΈ°λ³Έ 클래슀 μ—­ν• μ„ν•©λ‹ˆλ‹€. κ·Έλ ‡μ§€ μ•ŠμœΌλ©΄ μΈμŠ€ν„΄μŠ€μ—λŠ” μ˜ˆμ™Έλ₯Ό λ°œμƒμ‹œν‚€μ§€ μ•Šκ³  호좜 ν•  μˆ˜μ—†λŠ” λ©”μ†Œλ“œκ°€ μžˆμŠ΅λ‹ˆλ‹€.

일뢀 μ†ŒμŠ€κ°€ μΆ”κ°€ν•˜λŠ” μ œμ•½ 쑰건은 ν΄λž˜μŠ€μ— 데이터가없고 λ©”μ„œλ“œ 만 포함될 수 μžˆμ§€λ§Œ 이것이 μ™œ ν•„μš”ν•œμ§€ μ•Œ 수 μ—†λ‹€λŠ” κ²ƒμž…λ‹ˆλ‹€. κ·ΈλŸ¬λ‚˜ μ‹€μ œλ‘œ λ§Žμ€ μœ μš©ν•œ 믹슀 μΈμ—λŠ” 데이터가 μ—†μœΌλ©° λ°μ΄ν„°κ°€μ—†λŠ” κΈ°λ³Έ ν΄λž˜μŠ€λŠ” μ‚¬μš©ν•˜κΈ°κ°€ 더 μ‰½μŠ΅λ‹ˆλ‹€.

μ „ν˜•μ μΈ μ˜ˆλŠ” λͺ¨λ“  비ꡐ μ—°μ‚°μžμ˜ κ΅¬ν˜„ <=κ³Ό ==:

class ComparableMixin(object):
    """This class has methods which use `<=` and `==`,
    but this class does NOT implement those methods."""
    def __ne__(self, other):
        return not (self == other)
    def __lt__(self, other):
        return self <= other and (self != other)
    def __gt__(self, other):
        return not self <= other
    def __ge__(self, other):
        return self == other or self > other

class Integer(ComparableMixin):
    def __init__(self, i):
        self.i = i
    def __le__(self, other):
        return self.i <= other.i
    def __eq__(self, other):
        return self.i == other.i

assert Integer(0) <  Integer(1)
assert Integer(0) != Integer(1)
assert Integer(1) >  Integer(0)
assert Integer(1) >= Integer(1)

# It is possible to instantiate a mixin:
o = ComparableMixin()
# but one of its methods raise an exception:
#o != o 

이 νŠΉλ³„ν•œ μ˜ˆλŠ” functools.total_ordering()λ°μ½”λ ˆμ΄ν„° λ₯Ό 톡해 달성 ν•  수 μžˆμ—ˆμ§€λ§Œ μ—¬κΈ°μ„œ κ²Œμž„μ€ 바퀴λ₯Ό 재발 λͺ…ν•˜λŠ” 것이 μ—ˆμŠ΅λ‹ˆλ‹€

import functools

@functools.total_ordering
class Integer(object):
    def __init__(self, i):
        self.i = i
    def __le__(self, other):
        return self.i <= other.i
    def __eq__(self, other):
        return self.i == other.i

assert Integer(0) < Integer(1)
assert Integer(0) != Integer(1)
assert Integer(1) > Integer(0)
assert Integer(1) >= Integer(1)

μ •μ˜ 2 : 닀쀑 상속

믹슀 인은 κΈ°λ³Έ 클래슀의 일뢀 λ©”μ†Œλ“œκ°€ μ •μ˜ν•˜μ§€ μ•Šμ€ λ©”μ†Œλ“œλ₯Ό μ‚¬μš©ν•˜λŠ” λ””μžμΈ νŒ¨ν„΄μ΄λ©°, ν•΄λ‹Ή λ©”μ†Œλ“œλŠ” μ •μ˜ 1μ—μ„œ νŒŒμƒ 된 것이 μ•„λ‹ˆλΌ λ‹€λ₯Έ κΈ°λ³Έ ν΄λž˜μŠ€μ— μ˜ν•΄ κ΅¬ν˜„λ˜μ–΄μ•Όν•©λ‹ˆλ‹€ .

mixin 클래슀 λΌλŠ” μš©μ–΄ λŠ” ν•΄λ‹Ή λ””μžμΈ νŒ¨ν„΄μ— μ‚¬μš©λ˜λŠ” κΈ°λ³Έ 클래슀 (λ©”μ†Œλ“œλ₯Ό μ‚¬μš©ν•˜λŠ” 클래슀 λ˜λŠ” λ©”μ†Œλ“œλ₯Ό κ΅¬ν˜„ν•˜λŠ” 클래슀)λ₯Ό λ‚˜νƒ€λƒ…λ‹ˆλ‹€.

μ£Όμ–΄μ§„ ν΄λž˜μŠ€κ°€ 믹슀 인인지 μ•„λ‹Œμ§€λ₯Ό κ²°μ •ν•˜λŠ” 것은 쉽지 μ•ŠμŠ΅λ‹ˆλ‹€. λ©”μ†Œλ“œλŠ” νŒŒμƒ ν΄λž˜μŠ€μ—μ„œ κ΅¬ν˜„ 될 수 μžˆμŠ΅λ‹ˆλ‹€.이 경우 μ •μ˜ 1둜 λŒμ•„κ°‘λ‹ˆλ‹€. μ €μžμ˜ μ˜λ„λ₯Ό κ³ λ €ν•΄μ•Όν•©λ‹ˆλ‹€.

이 νŒ¨ν„΄μ€ λ‹€λ₯Έ κΈ°λ³Έ 클래슀 μ„ νƒμœΌλ‘œ κΈ°λŠ₯을 μž¬κ²°ν•© ν•  수 있기 λ•Œλ¬Έμ— ν₯λ―Έ λ‘­μŠ΅λ‹ˆλ‹€.

class HasMethod1(object):
    def method(self):
        return 1

class HasMethod2(object):
    def method(self):
        return 2

class UsesMethod10(object):
    def usesMethod(self):
        return self.method() + 10

class UsesMethod20(object):
    def usesMethod(self):
        return self.method() + 20

class C1_10(HasMethod1, UsesMethod10): pass
class C1_20(HasMethod1, UsesMethod20): pass
class C2_10(HasMethod2, UsesMethod10): pass
class C2_20(HasMethod2, UsesMethod20): pass

assert C1_10().usesMethod() == 11
assert C1_20().usesMethod() == 21
assert C2_10().usesMethod() == 12
assert C2_20().usesMethod() == 22

# Nothing prevents implementing the method
# on the base class like in Definition 1:

class C3_10(UsesMethod10):
    def method(self):
        return 3

assert C3_10().usesMethod() == 13

κΆŒμœ„μžˆλŠ” 파이썬 μ–΄μ»€λŸ°μŠ€

collections.abc에 λŒ€ν•œ 곡식 λ¬Έμ„œ μ—μ„œ μ„€λͺ…μ„œλŠ” Mixin Methods λΌλŠ” μš©μ–΄λ₯Ό λͺ…μ‹œ 적으둜 μ‚¬μš©ν•©λ‹ˆλ‹€ .

그것은 클래슀라면 :

  • κ΅¬ν˜„ν•˜λ‹€ __next__
  • 단일 ν΄λž˜μŠ€μ—μ„œ 상속 Iterator

그런 λ‹€μŒ ν΄λž˜μŠ€λŠ” 무료 둜 __iter__ mixin λ©”μ†Œλ“œ λ₯Ό μ–»μŠ΅λ‹ˆλ‹€ .

λ”°λΌμ„œ μ΅œμ†Œν•œμ΄ λ¬Έμ„œμ˜ μ‹œμ μ—μ„œ mixin은 닀쀑 상속을 μš”κ΅¬ν•˜μ§€ μ•ŠμœΌλ©° μ •μ˜ 1κ³Ό μΌμΉ˜ν•©λ‹ˆλ‹€.

λ¬Όλ‘  λ¬Έμ„œλŠ” λ‹€λ₯Έ μ‹œμ μ—μ„œ λͺ¨μˆœ 될 수 있으며 λ‹€λ₯Έ μ€‘μš”ν•œ Python λΌμ΄λΈŒλŸ¬λ¦¬λŠ” λ¬Έμ„œμ—μ„œ λ‹€λ₯Έ μ •μ˜λ₯Ό μ‚¬μš©ν•˜κ³ μžˆμ„ 수 μžˆμŠ΅λ‹ˆλ‹€.

이 νŽ˜μ΄μ§€λŠ” λ˜ν•œ μš©μ–΄λ₯Ό μ‚¬μš©ν•©λ‹ˆλ‹€.이 μš©μ–΄ Set mixinλŠ” 클래슀λ₯Ό Mixin 클래슀 Set와 κ°™κ³  Iterator호좜 ν•  수 μžˆμŒμ„ λͺ…ν™•ν•˜κ²Œ μ œμ•ˆν•©λ‹ˆλ‹€ .

λ‹€λ₯Έ μ–Έμ–΄λ‘œ

  • Ruby : Programming Ruby 및 The Ruby programming Language와 같은 μ£Όμš” μ°Έκ³ μ„œμ—μ„œ μ–ΈκΈ‰ ν•œ κ²ƒμ²˜λŸΌ mixin에 λŒ€ν•΄ 닀쀑 상속이 ν•„μš”ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.

  • C ++ : κ΅¬ν˜„λ˜μ§€ μ•Šμ€ λ©”μ†Œλ“œλŠ” μˆœμˆ˜ν•œ 가상 λ©”μ†Œλ“œμž…λ‹ˆλ‹€.

    μ •μ˜ 1은 좔상 클래슀 (순수 가상 λ©”μ„œλ“œκ°€μžˆλŠ” 클래슀)의 μ •μ˜μ™€ μΌμΉ˜ν•©λ‹ˆλ‹€. ν•΄λ‹Ή ν΄λž˜μŠ€λŠ” μΈμŠ€ν„΄μŠ€ν™” ν•  수 μ—†μŠ΅λ‹ˆλ‹€.

    μ •μ˜ 2λŠ” 가상 μƒμ†μœΌλ‘œ κ°€λŠ₯ν•©λ‹ˆλ‹€. 두 개의 νŒŒμƒ ν΄λž˜μŠ€μ—μ„œ 닀쀑 상속


λ‹΅λ³€

λ‚˜λŠ” 그것듀을 닀쀑 상속을 μ‚¬μš©ν•˜λŠ” ν›ˆλ ¨ 된 λ°©λ²•μœΌλ‘œ μƒκ°ν•©λ‹ˆλ‹€. ꢁ극적으둜 mixin은 mixinμ΄λΌλŠ” ν΄λž˜μŠ€μ— λŒ€ν•œ κ·œμΉ™μ„ λ”°λ₯΄λŠ” λ‹€λ₯Έ 파이썬 클래슀이기 λ•Œλ¬Έμž…λ‹ˆλ‹€.

Mixin이라고 λΆ€λ₯΄λŠ” 것을 μ§€λ°°ν•˜λŠ” κ·œμΉ™μ— λŒ€ν•œ λ‚˜μ˜ μ΄ν•΄λŠ” Mixinμž…λ‹ˆλ‹€.

  • λ©”μ†Œλ“œλ₯Ό μΆ”κ°€ν•˜μ§€λ§Œ μΈμŠ€ν„΄μŠ€ λ³€μˆ˜λŠ” μΆ”κ°€ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€ (클래슀 μƒμˆ˜λŠ” 정상 μž„)
  • 만 상속 object(파이썬)

κ·Έλ ‡κ²Œν•˜λ©΄ 닀쀑 μƒμ†μ˜ 잠재적 λ³΅μž‘μ„±μ„ μ œν•œν•˜κ³ , 전체 닀쀑 상속과 λΉ„κ΅ν•˜μ—¬ λ³Ό μœ„μΉ˜λ₯Ό μ œν•œν•˜μ—¬ ν”„λ‘œκ·Έλž¨ 흐름을 ν•©λ¦¬μ μœΌλ‘œ μ‰½κ²Œ 좔적 ν•  수 μžˆμŠ΅λ‹ˆλ‹€. 그것듀은 루비 λͺ¨λ“ˆ κ³Ό λΉ„μŠ· ν•©λ‹ˆλ‹€ .

μΈμŠ€ν„΄μŠ€ λ³€μˆ˜λ₯Ό μΆ”κ°€ν•˜λ €λ©΄ (단일 μƒμ†μœΌλ‘œ ν—ˆμš©λ˜λŠ” 것보닀 μœ μ—°μ„±μ΄ λ†’μŒ) μ»΄ν¬μ§€μ…˜μ„ μ„ ν˜Έν•©λ‹ˆλ‹€.

λ§ν–ˆλ“―μ΄ μΈμŠ€ν„΄μŠ€ λ³€μˆ˜κ°€μžˆλŠ” XYZMixinμ΄λΌλŠ” 클래슀λ₯Ό λ³΄μ•˜μŠ΅λ‹ˆλ‹€.


λ‹΅λ³€

믹슀 인은 ν”„λ‘œκ·Έλž˜λ°μ—μ„œ ν΄λž˜μŠ€κ°€ κΈ°λŠ₯을 μ œκ³΅ν•˜λŠ” κ°œλ…μ΄μ§€λ§Œ μΈμŠ€ν„΄μŠ€ν™”μ—λŠ” μ‚¬μš©λ˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€. 믹슀 인의 μ£Όμš” λͺ©μ μ€ λ…λ¦½ν˜• κΈ°λŠ₯을 μ œκ³΅ν•˜λŠ” 것이며 믹슀 인 μžμ²΄κ°€ λ‹€λ₯Έ 믹슀 인과 μƒμ†λ˜μ§€ μ•Šκ³  μƒνƒœλ₯Ό ν”Όν•˜λŠ” 것이 κ°€μž₯ μ’‹μŠ΅λ‹ˆλ‹€. Ruby와 같은 μ–Έμ–΄μ—λŠ” 직접적인 μ–Έμ–΄ 지원이 μžˆμ§€λ§Œ Python의 κ²½μš°μ—λŠ” μ§€μ›λ˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€. κ·ΈλŸ¬λ‚˜ 닀쀑 클래슀 상속을 μ‚¬μš©ν•˜μ—¬ Pythonμ—μ„œ μ œκ³΅ν•˜λŠ” κΈ°λŠ₯을 μ‹€ν–‰ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

믹슀 인의 κΈ°λ³Έ 사항을 μ΄ν•΄ν•˜κΈ° μœ„ν•΄ http://www.youtube.com/watch?v=v_uKI2NOLEM λΉ„λ””μ˜€λ₯Ό λ³΄μ•˜μŠ΅λ‹ˆλ‹€ . μ΄ˆλ³΄μžλŠ” 믹슀 인의 κΈ°λ³Έ 사항과 믹슀 인의 μž‘λ™ 방식 및이λ₯Ό κ΅¬ν˜„ν•  λ•Œ 직면 ν•  μˆ˜μžˆλŠ” 문제λ₯Ό μ΄ν•΄ν•˜λŠ” 것이 맀우 μœ μš©ν•©λ‹ˆλ‹€.

WikipediaλŠ” μ—¬μ „νžˆ μ΅œκ³ μž…λ‹ˆλ‹€ : http://en.wikipedia.org/wiki/Mixin


λ‹΅λ³€

믹슀 인과 닀쀑 상속을 λΆ„λ¦¬ν•˜λŠ” 것은 λ¬΄μ—‡μž…λ‹ˆκΉŒ? 의미둠의 문제 일까?

믹슀 인은 μ œν•œλœ ν˜•νƒœμ˜ 닀쀑 μƒμ†μž…λ‹ˆλ‹€. 일뢀 μ–Έμ–΄μ—μ„œλŠ” ν΄λž˜μŠ€μ— 믹슀 인을 μΆ”κ°€ν•˜λŠ” λ©”μ»€λ‹ˆμ¦˜μ΄ 상속과 μ•½κ°„ λ‹€λ¦…λ‹ˆλ‹€ (ꡬ문의 κ΄€μ μ—μ„œ).

특히 파이썬과 κ΄€λ ¨ν•˜μ—¬ 믹슀 인은 μ„œλΈŒ ν΄λž˜μŠ€μ— κΈ°λŠ₯을 μ œκ³΅ν•˜μ§€λ§Œ μΈμŠ€ν„΄μŠ€ν™”λ˜μ§€λŠ” μ•ŠλŠ” μƒμœ„ ν΄λž˜μŠ€μž…λ‹ˆλ‹€.

β€œμ‹€μ œλ‘œ 믹슀 인이 μ•„λ‹Œ 닀쀑 상속에 λΆˆκ³Όν•˜λ‹€β€κ³  말할 μˆ˜μžˆλŠ” 것은 믹슀 인에 λŒ€ν•΄ ν˜Όλž€ 슀러울 μˆ˜μžˆλŠ” ν΄λž˜μŠ€κ°€ μ‹€μ œλ‘œ μΈμŠ€ν„΄μŠ€ν™”λ˜μ–΄ μ‚¬μš©λ  수 μžˆλ‹€λ©΄ μ‹€μ œλ‘œ 의미 둠적이며 맀우 μ‹€μ§ˆμ μΈ μ°¨μ΄μž…λ‹ˆλ‹€.

닀쀑 μƒμ†μ˜ 예

documentation 의이 예제 λŠ” OrderedCounterμž…λ‹ˆλ‹€.

class OrderedCounter(Counter, OrderedDict):
     'Counter that remembers the order elements are first encountered'

     def __repr__(self):
         return '%s(%r)' % (self.__class__.__name__, OrderedDict(self))

     def __reduce__(self):
         return self.__class__, (OrderedDict(self),)

그것은 λͺ¨λ‘ μ„œλΈŒ 클래슀 Counter와λ₯Ό OrderedDictμœΌλ‘œλΆ€ν„° collectionsλͺ¨λ“ˆ.

λͺ¨λ‘ Counter와 OrderedDictμΈμŠ€ν„΄μŠ€ μžμ‹ μ— μ‚¬μš©ν•˜κΈ°μœ„ν•œ κ²ƒμž…λ‹ˆλ‹€. κ·ΈλŸ¬λ‚˜ 두 클래슀λ₯Ό λͺ¨λ‘ μ„œλΈŒ 클래 μ‹±ν•˜λ©΄ μΉ΄μš΄ν„°κ°€ μ •λ ¬λ˜μ–΄ 각 개체의 μ½”λ“œλ₯Ό μž¬μ‚¬μš© ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

이것은 μ½”λ“œλ₯Ό μž¬μ‚¬μš©ν•˜λŠ” κ°•λ ₯ν•œ λ°©λ²•μ΄μ§€λ§Œ λ¬Έμ œκ°€ 될 μˆ˜λ„ μžˆμŠ΅λ‹ˆλ‹€. 객체 쀑 ν•˜λ‚˜μ— λ²„κ·Έκ°€μžˆλŠ” κ²ƒμœΌλ‘œ λ°ν˜€μ§€λ©΄μ£Όμ˜μ—†μ΄ μˆ˜μ •ν•˜λ©΄ μ„œλΈŒ ν΄λž˜μŠ€μ— 버그가 λ°œμƒν•  수 μžˆμŠ΅λ‹ˆλ‹€.

믹슀 인의 예

믹슀 인은 일반적으둜 OrderedCounter와 같은 ν˜‘λ™ 닀쀑 상속이 κ°€μ§ˆ μˆ˜μžˆλŠ” 잠재적 인 μ»€ν”Œ 링 λ¬Έμ œμ—†μ΄ μ½”λ“œ μž¬μ‚¬μš©μ„ μ–»λŠ” λ°©λ²•μœΌλ‘œ ν™λ³΄λ©λ‹ˆλ‹€. 믹슀 인을 μ‚¬μš©ν•  λ•ŒλŠ” 데이터와 λ°€μ ‘ν•œ κ΄€λ ¨μ΄μ—†λŠ” κΈ°λŠ₯을 μ‚¬μš©ν•©λ‹ˆλ‹€.

μœ„μ˜ μ˜ˆμ™€ 달리 믹슀 인은 λ‹¨λ…μœΌλ‘œ μ‚¬μš©ν•˜λ„λ‘ μ˜λ„λ˜μ§€ μ•Šμ•˜μŠ΅λ‹ˆλ‹€. μƒˆλ‘­κ±°λ‚˜ λ‹€λ₯Έ κΈ°λŠ₯을 μ œκ³΅ν•©λ‹ˆλ‹€.

예λ₯Ό λ“€μ–΄, ν‘œμ€€ λΌμ΄λΈŒλŸ¬λ¦¬μ—λŠ” λΌμ΄λΈŒλŸ¬λ¦¬μ— 두 개의 믹슀 인이 socketserverμžˆμŠ΅λ‹ˆλ‹€ .

μ΄λŸ¬ν•œ ν˜Όν•© 클래슀λ₯Ό μ‚¬μš©ν•˜μ—¬ 각 μ„œλ²„ μœ ν˜•μ˜ 포크 및 μŠ€λ ˆλ”© 버전을 μž‘μ„±ν•  수 μžˆμŠ΅λ‹ˆλ‹€. 예λ₯Ό λ“€μ–΄ ThreadingUDPServerλŠ” λ‹€μŒκ³Ό 같이 μƒμ„±λ©λ‹ˆλ‹€.

class ThreadingUDPServer(ThreadingMixIn, UDPServer):
    pass

믹슀 인 ν΄λž˜μŠ€λŠ” UDPServer에 μ •μ˜ 된 λ©”μ†Œλ“œλ₯Ό λŒ€μ²΄ν•˜λ―€λ‘œ 믹슀 ν΄λž˜μŠ€κ°€ μš°μ„ ν•©λ‹ˆλ‹€. λ‹€μ–‘ν•œ 속성을 μ„€μ •ν•˜λ©΄ κΈ°λ³Έ μ„œλ²„ λ©”μ»€λ‹ˆμ¦˜μ˜ λ™μž‘λ„ λ³€κ²½λ©λ‹ˆλ‹€.

이 경우 mixin λ©”μ†Œλ“œ UDPServerλŠ” λ™μ‹œμ„±μ„ ν—ˆμš©ν•˜κΈ° μœ„ν•΄ 였브젝트 μ •μ˜ 의 λ©”μ†Œλ“œλ₯Ό λŒ€μ²΄ν•©λ‹ˆλ‹€ .

μž¬μ •μ˜ 된 λ©”μ„œλ“œκ°€μžˆλŠ” κ²ƒμ²˜λŸΌ 보이며 process_requestλ‹€λ₯Έ λ©”μ„œλ“œλ„ μ œκ³΅ν•©λ‹ˆλ‹€ process_request_thread. λ‹€μŒμ€ μ†ŒμŠ€ μ½”λ“œ μ—μ„œ κ°€μ Έμ˜¨ κ²ƒμž…λ‹ˆλ‹€ .

class ThreadingMixIn:
        """Mix-in class to handle each request in a new thread."""

        # Decides how threads will act upon termination of the
        # main process
        daemon_threads = False

        def process_request_thread(self, request, client_address):
            """Same as in BaseServer but as a thread.
            In addition, exception handling is done here.
            """
            try:
                self.finish_request(request, client_address)
            except Exception:
                self.handle_error(request, client_address)
            finally:
                self.shutdown_request(request)

        def process_request(self, request, client_address):
            """Start a new thread to process the request."""
            t = threading.Thread(target = self.process_request_thread,
                                 args = (request, client_address))
            t.daemon = self.daemon_threads
            t.start()

κ³ μ•ˆλœ 예

이것은 λŒ€λΆ€λΆ„ 데λͺ¨ λͺ©μ μœΌλ‘œ μ‚¬μš©λ˜λŠ” 믹슀 μΈμž…λ‹ˆλ‹€. λŒ€λΆ€λΆ„μ˜ κ°μ²΄λŠ”μ΄ repr의 μœ μš©μ„±μ„ λ„˜μ–΄μ„œ μ§„ν™” ν•  κ²ƒμž…λ‹ˆλ‹€.

class SimpleInitReprMixin(object):
    """mixin, don't instantiate - useful for classes instantiable
    by keyword arguments to their __init__ method.
    """
    __slots__ = () # allow subclasses to use __slots__ to prevent __dict__
    def __repr__(self):
        kwarg_strings = []
        d = getattr(self, '__dict__', None)
        if d is not None:
            for k, v in d.items():
                kwarg_strings.append('{k}={v}'.format(k=k, v=repr(v)))
        slots = getattr(self, '__slots__', None)
        if slots is not None:
            for k in slots:
                v = getattr(self, k, None)
                kwarg_strings.append('{k}={v}'.format(k=k, v=repr(v)))
        return '{name}({kwargs})'.format(
          name=type(self).__name__,
          kwargs=', '.join(kwarg_strings)
          )

μ‚¬μš©λ²•μ€ λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€.

class Foo(SimpleInitReprMixin): # add other mixins and/or extend another class here
    __slots__ = 'foo',
    def __init__(self, foo=None):
        self.foo = foo
        super(Foo, self).__init__()

그리고 μ‚¬μš©λ²• :

>>> f1 = Foo('bar')
>>> f2 = Foo()
>>> f1
Foo(foo='bar')
>>> f2
Foo(foo=None)

λ‹΅λ³€

λ‚˜λŠ” 여기에 쒋은 μ„€λͺ…이 μžˆλ‹€κ³  μƒκ°ν•˜μ§€λ§Œ λ‹€λ₯Έ 관점을 μ œκ³΅ν•˜κ³  μ‹Άμ—ˆμŠ΅λ‹ˆλ‹€.

μŠ€μΉΌλΌμ—μ„œλŠ” 여기에 μ„€λͺ… λœλŒ€λ‘œ 믹슀 인을 μˆ˜ν–‰ ν•  수 μžˆμ§€λ§Œ 맀우 ν₯미둜운 점은 믹슀 인이 μ‹€μ œλ‘œ β€˜μœ΅ν•©λ˜μ–΄β€™μƒμ† ν•  μƒˆλ‘œμš΄ μ’…λ₯˜μ˜ 클래슀λ₯Ό μƒμ„±ν•œλ‹€λŠ” κ²ƒμž…λ‹ˆλ‹€. 본질적으둜 μ—¬λŸ¬ 클래슀 / 믹슀 μΈμ—μ„œ μƒμ†ν•˜λŠ” 것이 μ•„λ‹ˆλΌ 상속 ν•  믹슀 인의 λͺ¨λ“  속성을 μ‚¬μš©ν•˜μ—¬ μƒˆλ‘œμš΄ μ’…λ₯˜μ˜ 클래슀λ₯Ό μƒμ„±ν•©λ‹ˆλ‹€. ScalaλŠ” 닀쀑 상속이 ν˜„μž¬ μ§€μ›λ˜μ§€ μ•ŠλŠ” JVM을 κΈ°λ°˜μœΌλ‘œν•˜κΈ° λ•Œλ¬Έμ— μ˜λ―Έκ°€ μžˆμŠ΅λ‹ˆλ‹€ (Java 8 κΈ°μ€€). 그건 κ·Έλ ‡κ³ ,이 믹슀 인 클래슀 μœ ν˜•μ€ 슀칼라의 νŠΉμ„±μ΄λΌκ³ ν•˜λŠ” 특수 μœ ν˜•μž…λ‹ˆλ‹€.

ν΄λž˜μŠ€κ°€ μ •μ˜ 된 λ°©μ‹μœΌλ‘œ μ•”μ‹œλ˜μ—ˆμŠ΅λ‹ˆλ‹€ : NewClass ν΄λž˜μŠ€λŠ” ThirdMixin으둜 FirstMixin을 ThirdMixin으둜 ν™•μž₯ν•©λ‹ˆλ‹€ …

CPython 인터프리터가 λ™μΌν•œ μž‘μ—…μ„ μˆ˜ν–‰ν•˜λŠ”μ§€ ν™•μ‹€ν•˜μ§€ μ•Šμ§€λ§Œ (mixin class-composition) 놀라지 μ•Šμ„ κ²ƒμž…λ‹ˆλ‹€. λ˜ν•œ C ++ λ°°κ²½μ—μ„œ λ‚˜λŠ” 믹슀 인에 ν•΄λ‹Ήν•˜λŠ” ABC λ˜λŠ” β€˜μΈν„°νŽ˜μ΄μŠ€β€™λ₯Ό ν˜ΈμΆœν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€. μœ μ‚¬ν•œ κ°œλ…μ΄μ§€λ§Œ μ‚¬μš© 및 κ΅¬ν˜„μ΄ λ‹€μ–‘ν•©λ‹ˆλ‹€.


이 글은 Python μΉ΄ν…Œκ³ λ¦¬λ‘œ λΆ„λ₯˜λ˜μ—ˆκ³  λ‹˜μ— μ˜ν•΄ 에 μž‘μ„±λμŠ΅λ‹ˆλ‹€.