β Programming Python βμμ Mark Lutzλ βmixinsβλ₯Ό μΈκΈν©λλ€. λλ C / C ++ / C # λ°°κ²½μμ μμΌλ©° μ΄μ μ©μ΄λ₯Ό λ£μ§ λͺ»νμ΅λλ€. λ―Ήμ€ μΈμ΄λ 무μμ λκΉ?
μ΄ μμ μ ν μ¬μ΄λ₯Ό μ½μΌλ©΄ (λ§€μ° κΈΈκΈ° λλ¬Έμ μ°κ²°λμ΄ μμ), βμλΉνβνμ ν΄λμ€μ λ¬λ¦¬ ν΄λμ€λ₯Ό νμ₯νκΈ° μν΄ λ€μ€ μμμ μ¬μ©νλ κ²½μ°λΌκ³ κ°μ ν©λλ€. μ΄κ² μ³μ κ±°λ?
μλ‘μ΄ κΈ°λ₯μ μλΈ ν΄λμ€μ λ£λ λμ μ κ·Έλ κ²νκ³ μΆμ΅λκΉ? κ·Έ μ μμ μ λ―Ήμ€ μΈ / λ©ν° μμ λ°©λ²μ΄ μ»΄ν¬μ§μ μ μ¬μ©νλ κ²λ³΄λ€ λ«μ΅λκΉ?
λ―Ήμ€ μΈκ³Ό λ€μ€ μμμ λΆλ¦¬νλ κ²μ 무μμ λκΉ? μλ―Έλ‘ μ λ¬Έμ μΌκΉ?
λ΅λ³
λ―Ήμ€ μΈμ νΉλ³ν μ’ λ₯μ λ€μ€ μμμ λλ€. λ―Ήμ€ μΈμ΄ μ¬μ©λλ λ κ°μ§ μ£Όμ μν©μ΄ μμ΅λλ€.
- μμ μ λ§μ μ΅μ κΈ°λ₯μ μ 곡νλ €κ³ ν©λλ€.
- λ§μ λ€λ₯Έ ν΄λμ€μμ νλμ νΉμ κΈ°λ₯μ μ¬μ©νλ €κ³ ν©λλ€.
첫 λ²μ§Έ μλ 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 λλ βμΈν°νμ΄μ€βλ₯Ό νΈμΆνμ§ μμ΅λλ€. μ μ¬ν κ°λ μ΄μ§λ§ μ¬μ© λ° κ΅¬νμ΄ λ€μν©λλ€.