我正在创建一个与我的 Python 项目等效的 Perl。
描述:我有一个基本模块“base.py”,我的所有脚本都通过“from base import *”使用该基本模块具有可以在脚本中执行的通用子例程/函数
我对 Perl 的尝试是放在每个脚本中“使用 base.pm”。然而,Perl 中的子程序并没有在本地导入到脚本中,所以每次我想执行子程序时都需要调用“基本”模块。什么是 Perl 等价于 Python 的“from base import *”?
我正在创建一个与我的 Python 项目等效的 Perl。
描述:我有一个基本模块“base.py”,我的所有脚本都通过“from base import *”使用该基本模块具有可以在脚本中执行的通用子例程/函数
我对 Perl 的尝试是放在每个脚本中“使用 base.pm”。然而,Perl 中的子程序并没有在本地导入到脚本中,所以每次我想执行子程序时都需要调用“基本”模块。什么是 Perl 等价于 Python 的“from base import *”?
一些东西:
Local
命名空间非常适合用于您的本地模块。Perl 专门Local
为此保留。命名空间中永远不会有官方模块Local
。如果您将完整的命名空间作为前缀,则您在模块中定义的所有函数都可用。这是定义和使用模块中的函数的最简单方法,也是最不可能引起问题的方法。很容易看出一个函数的来源,并且使用相同的函数名的两个模块不会有问题。
我有一个名为的模块Local::Base
,其中有一个函数。我的程序可以使用此功能,只需将其称为Local::Base::foo
:
use strict;
use warnings;
use feature qw(say);
use Local::Base;
my $foo_string = Local::Base::foo("string");
say "Foo: $foo_string";
package Local::Base;
use strict;
use warnings;
sub foo {
my $string = shift;
return qq(I've foo'd "$string"!);
}
1;
Exporter
Pragma 指定要自动导出的内容Perl 有一个名为Exporter的特殊编译指示,它允许我指定哪些模块将自动导入到我的程序中。
这不像 Python,我可以指定任何已定义的函数。相反,我必须列出我想要导出的那些。这与 Python 的方式相比有一个缺点:在 Python 中,如果我编写一个新函数,它会自动导入,而无需我做任何事情。与 Python 的方式相比,它还有一个很大的优势:在 Python 中,如果我编写一个新函数,它会自动导入,而无论我是否要导入它,我都无需做任何事情。你可以想象如果我写了一个我不想让人们使用的私有函数。在 Python 中,它将自动可用。在 Perl 中,除非我指定它,否则它不会是:
use strict;
use warnings;
use feature qw(say);
use Local::Base;
my $foo_string = foo("string");
say "Foo: $foo_string";
package Local::Base;
use strict;
use warnings;
use Exporter 'import';
our @EXPORT = qw(foo);
sub foo {
my $string = shift;
return qq(I've foo'd "$string"!);
}
1;
现在,每当我使用 时Local::Base
,都会自动导入该foo
功能。
请注意,我列出了要在@EXPORT
数组中导出的所有函数。our
(另请注意,我用 a而不是 a声明了该数组my
。这our
意味着 the@EXPORT
是一个 PACKAGE 变量。)。还要注意qw(...)
语法。这是引用词。所有单词都是数组的单独元素。您不使用逗号:
my @array = ("one", "two", "three");
my @array = qw(one two three);
这两者是等价的。你也可以这样看:
my @array = qw/one two three/;
我喜欢括号,但正斜杠往往是标准。
不建议您再使用自动导出。较旧的模块File::Copy
仍然可以这样做,但较新的模块会让您导入您的东西。这也使用了Exporter pragma,但我指定@EXPORT_OK
而不是仅指定@EXPORT
.
现在,当我指定要使用Local::Base
时,我必须指定要导入程序的函数:
use strict;
use warnings;
use feature qw(say);
use Local::Base qw(foo);
my $foo_string = foo("string");
say "Foo: $foo_string";
package Local::Base;
use strict;
use warnings;
use Exporter 'import';
our @EXPORT_OK; = qw(foo);
sub foo {
my $string = shift;
return qq(I've foo'd "$string"!);
}
1;
这迫使用户记录他们想要使用的模块中的功能。这样,他们就知道导入函数的来源。它强制执行良好的编程实践。另外,如果您使用多个模块并且它们具有相似的函数名称,您可以确保使用您想要的模块中的一个。(记住,如果你想使用另一个,你仍然可以在函数前指定包名前缀)。
如果我是一名 Python 程序员并且我不关心良好的编程实践怎么办?(等等,结果不太对劲……)你仍然可以(在某种程度上)通过指定正则表达式(毕竟这是 Perl)以 Python 的方式来做:
use Local::Base '/.+/';
这将导出两者中列出@EXPORT
并@EXPORT_OK
与此正则表达式匹配的所有模块。由于这匹配所有内容,因此它将导入您在@EXPORT
和中列出的所有内容@EXPORT_OK
。它不会导入所有功能。它只会导入@EXPORT
和@EXPORT_OK
数组中的函数。当然,您可以指定任何正则表达式,甚至是 ant 正则表达式。这将导出所有可导出的函数,但名称中的函数除外bar
:
use Local::Base '!/bar/';
看看Exporter pragma,看看它还有什么其他好处。例如,您可以将函数分组到标签中。这样,用户只需一个标签就可以指定一组特定的功能。请参阅Math::Trig以获得一个很好的示例。
希望这可以帮助。
对不起,答案很长,但我已婚并有孩子。就像,我在新年前夜做其他事情。
您通常指定要导入的函数,就像名称列表一样:
use List::Util 'max', 'min';
大多数导出内容的模块将遵循以下语义:
use MyBase; # imports default exports (if any)
use MyBase 'baz'; # imports only baz
use MyBase (); # import nothing
在模块内部,调用了一个导入类方法,该方法可以选择要导出的内容,通常有一个默认列表,但如果有一个则使用传递的列表。导出器模块可以帮助您做到这一点:
package MyBase;
use Exporter 'import';
our @EXPORT = ( 'foo', 'bar' );
our @EXPORT_OK = ( 'baz', 'quux' );
还有一个按标签对导出进行分组并允许轻松导入整个组的工具,请参阅导出器文档。变量也可以导出,而不仅仅是 subs。
有了这个背景,最后回答你的问题:
对于使用 Exporter 的模块(并非所有模块都这样做),您可以使用包含在 // 中的正则表达式指定导入:
use List::Util '/./';
首先base.pm
是一个非常糟糕的名字,因为它是一个核心模块。其次,可导出函数必须这样声明(通常),参见Exporter示例。