associação pythonbrasil[11] django zope/plone planet Início Logado como (Entrar)

Revisão 5e 2010-05-05 21:31:06

Excluir mensagem

VerificadorDeCPF

Receita: Verificador de CPF

Esse módulo contém algumas funções e classes úteis para aplicações que envolvam cadastros e necessitem validar números de CPF antes de incluir no banco de dados. Além de útil, também é um bom exemplo de como otimizar código que lida com manipulação de números e strings, usando as funções sum(), map() e list compreensions.

Código

   1 #/usr/bin/env python
   2 # -*- coding:UTF-8 -*-
   3 # fonte: http://www.python.org.br/wiki/VerificadorDeCPF
   4 
   5 import re
   6 
   7 # traduz 123.456.789-10 para 12345678910
   8 _translate = lambda cpf: ''.join(re.findall("\d", cpf))
   9 
  10 def _gen(cpf):
  11     """Gera o próximo dígito do número de CPF
  12 
  13     """
  14     res = []
  15     for i in range(len(cpf)):
  16         a = cpf[i]
  17         b = len(cpf) + 1 - i
  18         res.append(b * a)
  19 
  20     res = sum(res) % 11
  21 
  22     if res > 1:
  23         return 11 - res
  24     else:
  25         return 0
  26 
  27 
  28 class CPF(object):
  29 
  30     _gen = staticmethod(_gen)
  31     _translate = staticmethod(_translate)
  32     
  33     def __init__(self, cpf):
  34         """O argumento cpf pode ser uma string nas formas:
  35 
  36         12345678910
  37         123.456.789-10
  38 
  39         ou uma lista ou tuple
  40         [1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 0]
  41         (1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 0)
  42 
  43         """
  44         
  45         if isinstance(cpf, basestring):
  46             if not cpf.isdigit():
  47                cpf = self._translate(cpf)
  48             
  49         self.cpf = [int(x) for x in cpf]
  50 
  51     def __getitem__(self, index):
  52         """Retorna o dígito em index como string
  53 
  54         """
  55         
  56         return self.cpf[index]
  57 
  58     def __repr__(self):
  59         """Retorna uma representação 'real', ou seja:
  60 
  61         eval(repr(cpf)) == cpf
  62         
  63         """
  64         
  65         return "CPF('%s')" % ''.join([str(x) for x in self.cpf])
  66 
  67     def __eq__(self, other):
  68         """Provê teste de igualdade para números de CPF
  69 
  70         """
  71 
  72         if isinstance(other, CPF):
  73             return self.cpf == other.cpf
  74         return False
  75     
  76     def __str__(self):
  77         """Retorna uma representação do CPF na forma:
  78 
  79         123.456.789-10
  80 
  81         """
  82 
  83         d = iter("..-")
  84         s = map(str, self.cpf)
  85         for i in xrange(3, 12, 4):
  86             s.insert(i, d.next())
  87         r = ''.join(s)
  88         return r
  89 
  90     def isValid(self):
  91         """Valida o número de cpf
  92 
  93         """
  94         
  95         s = self.cpf[:9]
  96         s.append(self._gen(s))
  97         s.append(self._gen(s))
  98         return s == self.cpf[:]

Exemplo de uso

   1 #/usr/bin/env python
   2 # -*- coding:UTF-8 -*-
   3 
   4 
   5 from cpf import CPF
   6 
   7 # Estes números foram gerados aleatoriamente :)
   8 
   9 VALIDO = "113.451.253-80"
  10 INVALIDO = "31354110274"
  11 
  12 # qualquer um dos dois formatos (com pontos ou não) pode ser usado
  13 
  14 valido = CPF(VALIDO)
  15 invalido = CPF(INVALIDO)
  16 
  17 assert valido.isValid()
  18 assert invalido.isValid()

Volta para CookBook.


Pedro Werneck

edit 05/05/2010: Italo Maia