2014-04-28 6 views
2
class A(object): 

    def a(self, b=1): 
     print 'Up' 
    d = {1 : a} 

    def b(self): 
     print self.d[1] 
     print self.b 
     print self.d[1].__get__(self, A)() 
     # print self.d[1]() 

class B(object): 


    def a(self): 
     print 'here??' 
     return 10000 
    d = {1 : a} 
    def b(self): 
     print 'hurray' 

o = A() 
o.b() 

b = B() 
type(o).__dict__['b'].__get__(b, type(b))() 

Привет народ,Binding метод другого класса

Я шел через Python: Bind an Unbound Method? и http://users.rcn.com/python/download/Descriptor.htm и пытается экспериментировать на мое обучение.

Но я ударил новые сомнения в настоящее время: -

  1. В последней строке моего кода, я могу использовать __get__ с b объекта и, например: type(b). Это работает только в том случае, если метод b определен в class B. Почему это так?
  2. Несмотря на то, что последняя строка требует от меня указать метод b в class B, по-прежнему вызывается метод b в class A. Почему это так?
  3. К моему полному удивлению, после вышеуказанного шага я замечаю, что метод a от class A не вызывается кодом метода b из class A; вместо этого он вызывает метод a от class B. Почему это так?

Я довольно смущен, увидев это поведение. Мне также может понадобиться больше узнать о дескрипторах. Но, это было бы большим подспорьем, если вы могли бы ответить на мои сомнения

ответ

2

В последней строке моего кода, я могу использовать __get__ с объектом б и, например: type(b). Это работает только в том случае, если метод b определен в class B. Почему это так?

Вы должны определить метод b в классе B, потому что в A.b у вас есть print self.b. Здесь self является экземпляром класса B, поэтому self.b означает «метод b, принадлежащий этому B», а не «метод b, принадлежащий классу, который существует в этом методе». Если вы удалите print self.b, тогда код будет работать, даже если B не имеет b.

Даже если последняя строка требует от меня, чтобы обеспечить способ b в class B, еще метод b в class A будет вызываться. Почему это так?

A.b вызывается, потому что вы явно обращаетесь к нему с помощью type(o).__dict__['b']. Независимо от того, привязываете ли вы этот метод к экземпляру A или экземпляру B, это не имеет значения; это все еще A.b.

К моему удивлению, после того, как на предыдущем этапе, я заметил, что метод a из class A не вызывается кодом метода b из class A; вместо этого он вызывает метод a от class B. Почему это так?

Даже если b принадлежит к классу A, то self вы передаете к нему по-прежнему является экземпляром класса B. Любые атрибуты, которые вы получаете по этому self, будут атрибутами B, и любые методы, которые вы вызываете на него, будут B методов.

+0

Спасибо, Кевин. Но, может ли вы объяснить, что может быть реальным примером, в котором мы могли бы использовать 'type (o) .__ dict __ ['b'] .__ get __ (b, type (b))()' вместо 'ob__get __ (b, type (b))() '? Другими словами, связывает метод 'b'' класса A' с классом B' когда-либо возможным? Если да, то как и каковы практические случаи использования? – GodMan

+0

"связывает метод b класса A с классом B когда-либо возможным?" Это именно то, что вы делаете в своем коде. Получение 'self', чтобы притвориться, что это экземпляр A, является чем-то другим. В любом случае, я не думаю, что это практическое применение. Хороший код OO не должен пытаться «обмануть» среду, чтобы думать, что объект принадлежит классу, на котором он фактически не принадлежит. – Kevin

+0

Спасибо, что ответили на все мои вопросы. – GodMan

 Смежные вопросы

  • Нет связанных вопросов^_^