如果我想获得与内置print
类似的参数传递,如何声明函数原型,就像接受可选的第一个参数,即文件句柄?例如,调用语法为myprint $filehandle @mylist
。
答案 0 :(得分:3)
Perl subs。
无法复制print
的语法
$ perl -le'print defined(prototype("CORE::print")) ? "Can" : "Can'\''t", " be replicated"'
Can't be replicated
具体来说,语法NAME EXPR LIST
不能用于调用Perl子,因为语法用于间接方法调用。 NAME EXPR LIST
已经意味着EXPR->NAME(LIST)
选项1
# myprint $fh, LIST
# myprint *FH, LIST
# myprint \*FH, LIST
sub myprint {
my $fh = shift;
...
}
选项2
# myprint $fh, LIST
# myprint *FH, LIST
# myprint \*FH, LIST
# myprint FH, LIST
sub myprint(*@) {
my $fh = shift;
if (!ref($fh)) {
$fh = caller().'::'.$fh if $fh !~ /^(?:ARGV|STD(?:IN|OUT|ERR))\z/;
no strict qw( refs );
$fh = \*$fh;
}
...
}
另一方面,即使print
实际上也不支持print EXPR LIST
。它支持以下语法:
print LIST # Short for: print { select() } LIST
print IDENT LIST # Short for: print { \*IDENT } LIST
print $VAR LIST # Short for: print { $VAR } LIST
print BLOCK LIST
您实际上可以支持print
的最终形式(其他只是快捷方式):
# myprint { select } LIST
# myprint { $fh } LIST
# myprint { *FH } LIST
# myprint { \*FH } LIST
sub myprint(&@) {
my $fh = shift->();
...
}
我喜欢这个解决方案,而不是前两个。
答案 1 :(得分:2)
<td class="playerName md align-left pre in post" style="display: table-cell;"><span ...</span>
<a role="button" class="full-name">Dustin Johnson</a>
<a role="button" class="short-name">D. Johnson</a></td>
作为间接方法调用的示例,等同于
url = 'http://www.espn.com/golf/leaderboard?tournamentId=3742'
req = requests.get(url)
soup = bs4.BeautifulSoup(req.text,'lxml')
table = soup.find(id='leaderboard-view')
headings = [th.get_text() for th in table.find('tr').find_all('th')]
dataset = []
for row in table.find_all('tr'):
a = [td.get_text() for td in row.find_all('td')]
dataset.append(a)
要使用可以使用文件句柄间接调用的其他函数,请在print $fh @list
包中定义它。
$fh->print(@list)
这适用于Perl v5.16及更好,并且不适用于Perl v5.12及更早版本,原因我没有调查过(可能是因为它直到v5.14或v5.16)所有文件句柄都自动加入 IO::Handle
)
这似乎适用于所有版本的Perl,至少恢复到v5.8。 sub IO::Handle::myprint {
my ($self, @list) = @_;
#$self->print(scalar localtime,": ",@list);
print $self scalar localtime, ": ", @list;
}
open my $fh, '>', 'foo';
print $fh "hello\n"; # IO::Handle::print($fh, "hello\n")
myprint $fh "world\n"; # IO::Handle::myprint($fh, "world\n")
close $fh;
方法中的语法IO::File
需要v5.16(或者v5.14,只要所有文件句柄都被自动祝福$self->print(...)
) - {{1}仍然适用于较旧的Perls。