Частичный ответ для вас. Я опубликую пример кода, а затем объясню, почему это только частичный ответ.
Код:
class hidden(object): # or whatever its parent class is
def __init__(self):
self.value = 4
def show(self):
return self.value
def change(self,n):
self.value = n
def __getattr__(self, attrname):
# put the dep'd method/attribute names here
deprecateds = ['dep_show','dep_change']
if attrname in deprecateds:
print("These aren't the methods you're looking for.")
def dep_change(n):
self.value = n
def dep_show():
return self.value
return eval(attrname)
else:
raise AttributeError, attrname
Итак, теперь предостережение: они не методы (обратите внимание на отсутствие self в качестве первой переменной). Если вам нужно, чтобы ваши пользователи (или ваш код) могли вызывать im_class, im_func или im_self для любого из ваших устаревших методов, этот хак не будет работать. Кроме того, я уверен, что производительность снизится, потому что вы определяете каждую функцию dep'd внутри __getattr__
. Это не повлияет на другие ваши поиски атрибутов (если бы я поместил их в __getattribute__
, это было бы другое дело), но это замедлит доступ к этим устаревшим методам. Это можно (в значительной степени, но не полностью) отрицать, помещая каждое определение функции в свое собственное блок if, вместо того, чтобы выполнять проверку членства в списке, но, в зависимости от того, насколько велика ваша функция, это может быть действительно раздражающим для поддержки.
ОБНОВЛЕНИЕ:
1) Если вы хотите создать методы устаревших функций (и вы это делаете), просто используйте
import types
return types.MethodType(eval(attrname), self)
вместо
return eval(attrname)
в приведенном выше фрагменте и добавьте self в качестве первого аргумента функции defs. Он превращает их в методы экземпляра (так что вы можете использовать im_class, im_func и im_self для вашего сердца).
2) Если хук __getattr__
вас не заинтриговал, есть еще один вариант (который я знаю) (albiet, со своими собственными предостережениями, и мы к ним вернемся): поместите определения устаревших функций внутри __init__
, и скрыть их с помощью пользовательского __dir__
. Вот как будет выглядеть приведенный выше код, сделанный таким образом:
class hidden(object):
def __init__(self):
self.value = 4
from types import MethodType
def dep_show(self):
return self.value
self.__setattr__('dep_show', MethodType(dep_show, self))
def dep_change(self, n):
self.value = n
self.__setattr__('dep_change', MethodType(dep_change, self))
def show(self):
return self.value
def change(self, n):
self.value = n
def __dir__(self):
heritage = dir(super(self.__class__, self)) # inherited attributes
hide = ['dep_show', 'dep_change']
show = [k for k in self.__class__.__dict__.keys() + self.__dict__.keys() if not k in heritage + private]
return sorted(heritage + show)
Преимущество в том, что вы не определяете функции заново при каждом поиске, что ускоряет вашу работу. Недостатком здесь является то, что поскольку вы не определяете функции заново при каждом поиске, они должны «сохраняться» (если хотите). Таким образом, хотя пользовательский метод __dir__
скрывает ваши устаревшие от dir(hiddenObj)
и, следовательно, завершение вкладки IPython, они все еще существуют в атрибуте __dict__
экземпляра, где пользователи могут их обнаружить.