Можно использовать inspect.stack()
import inspect,os
inspect.stack()[0] => (<frame object at 0x00AC2AC0>, 'g:\\Python\\Test\\_GetCurrentProgram.py', 15, '<module>', ['print inspect.stack()[0]\n'], 0)
os.path.abspath (inspect.stack()[0][1]) => 'g:\\Python\\Test\\_GetCurrentProgram.py'
При использовании констант они реализуются как функции констант. ведет себя примерно так:
use subs 'BASE_PATH';
sub BASE_PATH () {"/data/monitor/"}
Любое использование BASE_PATH в программе является встроенным и поэтому не может быть изменено.
Для достижения подобного вы можете вручную использовать прагму subs (чтобы заставить BASE_PATH вести себя как встроенную функцию) и объявить BASE_PATH как стандартная функция:
use subs 'BASE_PATH';
sub BASE_PATH {"/data/monitor/"}
print "BASE_PATH is ".BASE_PATH."\n";
*BASE_PATH = sub {"/new/path"};
print "BASE_PATH is ".BASE_PATH."\n";
Хотя я не совсем уверен, зачем вам это нужно.
package My::Class; use constant BASE_PATH => "/a/real/value/"; # ..more code here.. 1;
Теперь в ваших модульных тестах:
use My::Class; *{My::Class::BASE_PATH} = sub { "/a/fake/value" }; # do your tests here...
Тесты часто выявляют негибкость дизайна. Это как-раз тот случай. Эта константа не должна быть постоянной.
Если вы делаете это из соображений производительности, я готов поспорить, что это не имеет никакого значения.
Очевидно, если ваше определение BASE_PATH было использовано / скомпилировано в другую подпрограмму ДО того, как ваш тест изменит его (через
*BASE_PATH = sub { ... }
или другой материал), у вас есть нет решения (потому что, когда исходный модуль использовал BASE_PATH как константу, он действительно определял функцию INLINE, которая была встроена при использовании в другом коде)