не уверенный, если, что, что Вы спрашиваете, но можно расширить существующие типы и затем назвать то, что Вы любите на новой вещи:
class int(int):
def random_method(self):
return 4 # guaranteed to be random
v = int(5) # you'll have to instantiate all you variables like this
v.random_method()
class int(int):
def xkcd(self):
import antigravity
print(42)
>>>v.xkcd()
Traceback (most recent call last):
File "<pyshell#81>", line 1, in <module>
v.xkcd()
AttributeError: 'int' object has no attribute 'xkcd'
c = int(1)
>>> c.random_method()
4
>>> c.xkcd()
42
надежда, которая разъясняет Ваш вопрос
Вы пропустили самое важное, самое большое различие между ними: glob
возвращает вам список, а opendir
дает вам дескриптор каталога. Вы можете передать этот дескриптор каталога, чтобы позволить другим объектам или подпрограммам использовать его. С дескриптором каталога подпрограмме или объекту не нужно ничего знать о том, откуда он пришел, кто еще его использует и т. Д.
sub use_any_dir_handle {
my( $dh ) = @_;
rewinddir $dh;
...do some filtering...
return \@files;
}
С помощью дескриптора dir у вас есть управляемый итератор, по которому вы можете перемещаться с помощью seekdir
, хотя с glob
вы просто получаете следующий элемент.
Однако, как и в любом другом случае, затраты и выгоды имеют смысл только при применении к определенному контексту. Они не существуют вне определенного использования. У вас есть отличный список их различий, но я бы не стал t классифицируйте эти различия, не зная, что вы пытались с ними сделать.
Еще кое-что, о чем следует помнить:
Вы можете реализовать свой собственный глобус с помощью opendir
, но не наоборот.
glob использует собственный синтаксис подстановочных знаков, и это все, что у вас есть.
glob может возвращать несуществующие имена файлов:
$ perl -le 'print glob "{ab} {cd}"'
glob pro: Может возвращать несуществующие «имена файлов»:
my @deck = List::Util::shuffle glob "{A,K,Q,J,10,9,8,7,6,5,4,3,2}{\x{2660},\x{2665},\x{2666},\x{2663}}";
while (my @hand = splice @deck,0,13) {
say join ",", @hand;
}
__END__
6♥,8♠,7♠,Q♠,K♣,Q♦,A♣,3♦,6♦,5♥,10♣,Q♣,2♠
2♥,2♣,K♥,A♥,8♦,6♠,8♣,10♠,10♥,5♣,3♥,Q♥,K♦
5♠,5♦,J♣,J♥,J♦,9♠,2♦,8♥,9♣,4♥,10♦,6♣,3♠
3♣,A♦,K♠,4♦,7♣,4♣,A♠,4♠,7♥,J♠,9♥,7♦,9♦
Ну, вы в значительной степени прикрыли это. Принимая во внимание все это, я бы предпочел использовать glob
, когда я создаю быстрый одноразовый скрипт, и его поведение является именно тем, что я хочу, и использую opendir
и readdir
в текущем производственном коде или библиотеках, где я могу не торопиться и более ясный, более чистый код полезен.
Для небольших простых вещей я предпочитаю glob
. Буквально на днях я использовал его вместе с Perl-скриптом из двадцати строк, чтобы изменить теги большой части моей музыкальной библиотеки. glob
, однако, имеет довольно странное имя. Глоб? Это совсем не интуитивно понятно, если говорить о названии.
Моя самая большая проблема с readdir
заключается в том, что он обращается с каталогом способом, который несколько странен для большинства людей. Обычно программисты не думают о каталоге как о потоке, они думают о нем как о ресурсе или списке, который предоставляет glob. Название лучше, функциональность лучше, но интерфейс все же оставляет желать лучшего.
Это был довольно полный список. readdir
(и readdir
+ grep
) имеет меньше накладных расходов, чем glob
, и это плюс для readdir
если вам нужно проанализировать очень много каталогов.
glob pros:
3) Нет необходимости добавлять имя каталога к элементам вручную
Исключение:
say for glob "*";
--output:--
1perl.pl
2perl.pl
2perl.pl.bak
3perl.pl
3perl.pl.bak
4perl.pl
data.txt
data1.txt
data2.txt
data2.txt.out
Насколько я могу судить, правило для glob
таково: вы должны указать полный путь к каталог, чтобы получить обратно полные пути. Документы Perl, похоже, не упоминают об этом, как и никакие другие сообщения здесь.
Это означает, что glob
можно использовать вместо readdir
, когда вам нужны только имена файлов (а не полные пути), и вы не хотите, чтобы возвращались скрытые файлы, т.е. начиная с '.'. Например,
chdir ("../..");
say for glob("*");
glob
позволяет удобно читать все подкаталоги заданной фиксированной глубины, как в glob "* / * / *"
. Я несколько раз находил это удобным.
Вот недостаток для opendir
и readdir
.
{
open my $file, '>', 0;
print {$file} 'Breaks while( readdir ){ ... }'
}
opendir my $dir, '.';
my $a = 0;
++$a for readdir $dir;
print $a, "\n";
rewinddir $dir;
my $b = 0;
++$b while readdir $dir;
print $b, "\n";
Можно было бы ожидать, что код выведет одно и то же число дважды, но это не так, потому что существует файл с именем 0
. На моем компьютере он печатает 251
, и 188
, проверено с Perl v5.10.0 и v5.10. 1
Эта проблема также делает так, что он просто печатает кучу пустых строк, независимо от существования файла 0
:
use 5.10.0;
opendir my $dir, '.';
say while readdir $dir;
В то время как это всегда работает просто отлично:
use 5.10.0;
my $a = 0;
++$a for glob '*';
say $a;
my $b = 0;
++$b while glob '*';
say $b;
say for glob '*';
say while glob '*';
Я исправил эти проблемы и послал патч, который вошел в Perl v5.11.2, так что это будет правильно работать с Perl v5.12.0, когда он выйдет.
Мое исправление преобразует this:
while( readdir $dir ){ ... }
в this:
while( defined( $_ = readdir $dir ){ ...}
Что заставляет его работать так же, как read
работал с файлами. На самом деле это тот же самый кусок кода, я просто добавил еще один элемент к соответствующим if
утверждениям.