- PVSM.RU - https://www.pvsm.ru -

Альтернативное описание паттернов проектирования: interpreter

Продолжение топика Альтернативное описание паттернов проектирования [1]

Interpreter [2] — решает часто встречающуюся, но подверженную изменениям, задачу.

На нашем, осмысленном примере это означает, что функцию поиска find класса FileSystem желательно обобщить на возможность поиска всех путей, куда искомая строка входит в качестве подстроки, а также на возможность работы с масками. Для этого можно воспользоватся регулярными выражениями [3] и стандартным модулем re [4] языка Python для работы с ними.

Для удобства сравнения кода с базовым примером [1], он слева, добавлена картинка аля — diff.

Изображение - savepic.su — сервис хранения изображений [5]

Сам код примера.

# -*- coding: utf-8 -*-

import re

fileSystem = None

class File:
  def __init__(self, size):
    self.size = size
    self.ind = fileSystem.create(self)
    self.parent = None

  def name(self):
    if not self.parent:
      return ""
    else:
      return self.parent.getName(self.ind)

class Dir:
  def __init__(self):
    self.ind = fileSystem.create(self)
    self.parent = None
    self.container = {}

  def getName(self, ind):
    return self.name() + self.container[ind]

  def name(self):
    if not self.parent:
      return ""
    else:
      return self.parent.getName(self.ind) + "/"

  def size(self):
    return len(self.container)

  def add(self, name, file):
    file.parent = self
    self.container[file.ind] = name

class Root(Dir):
  def __init__(self):
    Dir.__init__(self)

  def name(self):
    return "/"

class Link:
  def __init__(self, link):
    self.link = link
    self.ind = fileSystem.create(self)
    self.parent = None

  def name(self):
    if not self.parent:
      return " -> " + self.link.name()
    else:
      return self.parent.getName(self.ind) + " -> " + self.link.name()

  def size(self):
    return 8

class FileSystem:
  def __init__(self):
    self.container = {}

  def create(self, file):
    ind = hash(file)
    self.container[ind] = file
    return ind

  def find(self, name):
    pattern = re.compile(name)
    r = []
    for value in self.container.itervalues():
      if pattern.search(value.name()):
        r.append(value.name())
    return r

  def printAll(self):
    for value in self.container.itervalues():
      if isinstance(value, File):
        print "file: %8d %s" % (value.size, value.name())
      elif isinstance(value, Dir):
        print " dir: %8d %s" % (value.size(), value.name())
      elif isinstance(value, Link):
        print "link: %8d %s" % (value.size(), value.name())

if __name__ == "__main__":
  fileSystem = FileSystem()
  root = Root()
  etc = Dir()
  root.add("etc", etc)
  home = Dir()
  root.add("home", home)
  user = Dir()
  home.add("user", user)
  user.add("readme.txt", File(1177))
  user.add(".etc", Link(etc))
  fileSystem.printAll()
  print "find('/home/user')=", fileSystem.find("/home/user")
  print "find(r'.*.txt$')=", fileSystem.find(r".*.txt$")

В результате выполнения кода имеем некоторый повтор результата базового примера, а также совершенно другую работу функции поиска find. Они теперь ищет не точное совпадение, а все подстроки и умеет работать с масками заданными регулярными выражениями:

 dir:        2 /home/user/
file:     1177 /home/user/readme.txt
link:        8 /home/user/.etc -> /etc/
 dir:        2 /
 dir:        0 /etc/
 dir:        1 /home/
find('/home/user')= ['/home/user/', '/home/user/readme.txt', '/home/user/.etc -> /etc/']
find(r'.*.txt$')= ['/home/user/readme.txt']

Автор: bya


Сайт-источник PVSM.RU: https://www.pvsm.ru

Путь до страницы источника: https://www.pvsm.ru/python/14490

Ссылки в тексте:

[1] Альтернативное описание паттернов проектирования: http://habrahabr.ru/post/150780/

[2] Interpreter: http://ru.wikipedia.org/wiki/%D0%98%D0%BD%D1%82%D0%B5%D1%80%D0%BF%D1%80%D0%B5%D1%82%D0%B0%D1%82%D0%BE%D1%80_(%D1%88%D0%B0%D0%B1%D0%BB%D0%BE%D0%BD_%D0%BF%D1%80%D0%BE%D0%B5%D0%BA%D1%82%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F)

[3] регулярными выражениями: http://ru.wikipedia.org/wiki/%D0%A0%D0%B5%D0%B3%D1%83%D0%BB%D1%8F%D1%80%D0%BD%D1%8B%D0%B5_%D0%B2%D1%8B%D1%80%D0%B0%D0%B6%D0%B5%D0%BD%D0%B8%D1%8F

[4] re: http://www.intuit.ru/department/pl/python/6/python_6.html

[5] Image: http://savepic.su/1309163.htm