Если функция из исходного файла, доступного в файловой системе, может помочь inspect.getsource(foo)
:
Если foo
определяется как:
def foo(arg1,arg2):
#do something with args
a = arg1 + arg2
return a
Затем:
import inspect
lines = inspect.getsource(foo)
print(lines)
Возвраты:
def foo(arg1,arg2):
#do something with args
a = arg1 + arg2
return a
Но я считаю, что если функция скомпилирована из строки, потока или импортирована из скомпилированного файл, то вы не можете получить его исходный код.
Такое поведение продумано и тщательно продумано. Причина в том, что этот выбор смягчает влияние одной из форм отказа базового класса хрупкости.
Подробнее читайте в моей статье на эту тему.
http://blogs.msdn.com/ericlippert/archive/2007/09/04/future-breaking-changes-part-three.aspx
Это результат компилятора, мы исследовали код IL.
причина: производительность. вызов виртуального метода занимает немного больше времени. вызов делегата для виртуального метода занимает намного больше времени и так далее ....
.Причина в том, что это неоднозначно. Компилятору остается только выбрать один. И кто-то подумал, что менее косвенный вариант будет лучше (причина может быть в производительности). Если разработчик просто написал:
((Base)d).Foo (i);
, это ясно и дает ожидаемый результат.
Вот возможное объяснение:
Когда компилятор связывает вызовы методов, в первую очередь он смотрит на класс, который находится ниже в цепочке наследования (в данном случае производный
класс). Его методы экземпляра проверяются и сопоставляются. Переопределенный метод Foo не является методом экземпляра класса Derived
, он является методом экземпляра класса Base
.
Причиной этого может быть производительность, как предложил Jack30lena, но это может быть и то, как компилятор интерпретирует намерение кодера. Можно с уверенностью предположить, что предполагаемое разработчиком поведение кода находится в коде в нижней части цепочки наследования.