23 de jan. de 2018

Python para Engenheiros de Redes - Parte VII



Olá Pessoal Bom Dia, hoje vamos falar sobre funções.

O que é uma função?
Uma função é um bloco de código que serve para executar uma determinada tarefa. Dessa forma o nosso programa pode ser particionado em vários blocos de códigos, módulos, assim o nosso programa fica melhor organizado, gerenciável e com código reutilizável.

Vejamos um exemplo:

>>> ips
['192.168.100.1', '172.16.2.2', '10.10.10.3']
>>> for ip in ips:
...  octects=ip.split('.')
...  firstdigit=int(octects[0])
...  if firstdigit>=0 and firstdigit <128:
...   print "%s eh Clase A" % ip
...  elif firstdigit>=128 and firstdigit <192:
...   print "%s eh Clase B" % ip
...  elif firstdigit>=192 and firstdigit <224:
...   print "%s eh Clase C" % ip
...  else:
...   print "%s pertence a Clase D ou E" % ip
...
192.168.100.1 eh Clase C
172.16.2.2 eh Clase B
10.10.10.3 eh Clase A
>>>


O código acima lê vários endereços ip da lista “ips”, e verifica a classe a qual o endereço pertence.

Se por acaso mais adiante no código tivessemos uma outra lista, “ips_2” por exemplo, e quiser novamente saber a classe, vou precisar duplicar o mesmo código.

Para deixar o código mais organizado, modular e reutilizável, podemos criar uma função que aceite como entrada o primeiro dígito do endereço ip e retorne como resultado a classe.



>>> def verificaclasse(ipaddressfirstdigit):
...  if ipaddressfirstdigit>=0 and ipaddressfirstdigit <128:
...   classe='A'
...  elif ipaddressfirstdigit>128 and ipaddressfirstdigit <192:
...   classe='B'
...  elif ipaddressfirstdigit>=192 and ipaddressfirstdigit <224:
...   classe='C'
...  else:
...   classe='D ou E'
...  return classe
...
>>> for ip in ips:
...  octects=ip.split('.')
...  firstdigit=int(octects[0])
...  classe=verificaclasse(firstdigit)
...  print "%s pertence a Classe %s" % (ip,classe)
...
192.168.100.1 pertence a Classe C
172.16.2.2 pertence a Classe B
10.10.10.3 pertence a Classe A
>>>


Foi definida a função “verificaclasse”, que recebe como argumento o primeiro dígito do endereço ip, e ela retorna como resultado o valor da variável "classe", sentença “return classe” . A variavél "classe" contem o tipo de classe do endereço ip.



Sintaxes de uma função:
Acriação de uma função, começa pela utilização da palavra “def”, seguidamente do nome da função, logo entre parenteses, os parâmetros que dita função irá receber, separados por vírgulas caso seja mais de um parâmetro e finalizando com o símbolo “:”

Depois vem o código da função, com alguns níveis de indentação a mais que o cabeçalho da função.

Uma sentença “return” pode ser utilizada , caso seja preciso retornar algum valor.

def nome_funcao(parametros):
 código


Alguns exemplos:


>>> def imprimetexto(texto):
...  print texto
...
>>> s="Ola Mundo"
>>> imprimetexto(s)
Ola Mundo
>>>


No exemplo acima a função “imprimetexto” não retorna nenhum valor, somente imprime o parâmetro que ela recebe.



>>> def calculadora(a,b,operacao):
...  if operacao=='sum':
...   resultado=a+b
...  elif operacao=='subs':
...   resultado==a-b
...  elif operacao=='mult':
...   resultado=a*b
...  elif operacao=='div':
...   resultado=a/b
...  else:
...   resultado=0
...  return resultado
...
>>> a=10
>>> b=2
>>> calculadora(a,b,'sum')
12
>>> calculadora(a,b,'mult')
20
>>> result=calculadora(a,b,'div')
>>> result
5
>>>

A função calculadora recebe três parametros “a”,”b”, e o tipo de operação a ser executada, que pode ser “sum”,”subs”,”mult” e “div.

É interessante ver que o resultado que retorna à função, pode ser atribuída a uma outra variável no caso a variavél “result”.

Executando uma função:
Dos exemplos anteriores podemos ver que para executar uma função basta simplesmente chamar ela pela nome. Inclusive podemos chamar uma função dentro de outra função.


>>> def soma(a,b):
...  return a+b
...
>>> def subs(a,b):
...  return a-b
...
>>> def mult(a,b):
...  return a*b
...
>>> def div(a,b):
...  return a/b
...
>>> def calculadora(a,b,operacao):
...  if operacao=='sum':
...   resultado=soma(a,b)
...  elif operacao=='subs':
...   resultado=subs(a,b)
...  elif operacao=='mult':
...   resultado=mult(a,b)
...  elif operacao=='div':
...   resultado=div(a,b)
...  else:
...   resultado=0
...  return resultado
...
>>> a=10
>>> b=2
>>> result=calculadora(a,b,'mult')
>>> result
20
>>>
Agora foi definida uma função para cada operação aritmética: soma, subtração, multiplicação e divisão. Seguidamente foi definida a função calculadora a qual chama as funções previamente definidas.


Escopo e Tempo de vida das variavéis dentro de uma função:

O escopo vem a ser o bloco de código onde uma variável é reconhecida. Parâmetros e variáveis dentro do escopo de uma função são somente válidas dentro da função e não fora dela.

O tempo de vida de uma variável em uma função é o tempo que demora a função em ser executada. Uma vez que retornamos de uma função as variaveis dentro dela são destruídas.

Vejamos um exemplo para esclarecimento:



>>> def ssh_to_router(ip, username, password):
...  command='sh run'
...  print "Executando %s em router %s" % (command,ip)
...
>>> command='sh ip int bri'
>>> ssh_to_router('192.168.100.1','cisco','cisco')
Executando sh run em router 192.168.100.1
>>> command
'sh ip int bri'
>>>

No exemplo acima temos a variável “command”, ela existe no programa principal com o valor “sh ip int bri”. Dentro da função "ssh_to_router" temos uma variável com o mesmo nome "command", porém com um valor diferente “sh run”. A variável "command" dentro da função, somente vai existir durante o tempo que a função seja executada.


Importando módulos:
Muitas vezes, precisamos dividir o nosso programa principal em vários scripts python, afim de obter um projeto melhor organizado e gerenciável.

Exemplo:

Precisamos nos conectar via telnet ou ssh para nossos roteadores. Para isso criamos um script chamado “connect.py” onde podemos definir as funções de conexão para telnet e ssh:



connect.py

jose@rejane:~/CloudGuru$ more connect.py
#!/usr/bin/python
def telnet_connect(ip,username,password):
 print "Telnet Connection to %s" % ip

def ssh_connect(ip,username,password):
 print "SSH Connection to %s" % ip
jose@rejane:~/CloudGuru$

Agora criamos o nosso programa principal chamado de “testingconnection.py”, logo para poder utilizar as funções definidas no script “connect.py”, utilizamos a sentença “import”.  A notação para executar uma função do modulo importado é "modulo.funcao".


testingconnection.py 

jose@rejane:~/CloudGuru$ more testingconnection.py

#!/usr/bin/python
import connect

R1=['192.168.100.1','cisco','cisco']
R2=['192.168.100.2','cisco','cisco']

#Aqui utilizamos as funções importadas do script connect.py

connect.telnet_connect(R1[0],R1[1],R1[2])
connect.ssh_connect(R2[0],R2[1],R2[2])

jose@rejane:~/CloudGuru$


Quando rodamos o programa principal “testingconnection.py”, obtemos como resultado:

jose@rejane:~/CloudGuru$ ./testingconnection.py
Telnet Connection to 192.168.100.1
SSH Connection to 192.168.100.1
jose@rejane:~/CloudGuru$

Importar módulos é corriqueiro em python, isso porque a grande maioria das vezes já existem módulos prontos para serem utilizados em diversas situações. Por exemplo, módulos para se conectar a um banco MySql, módulo de conexão SSH Paramiko, módulo de algebra lineal numpy etc etc.

Bom Pessoal por hoje é isso ai, o próximo post vamos tratar um pouco de como trabalhar com arquivos, sentença with e tratamento de erros via try. Com isso finalizariamos os fundamentos de programação python. Daí para frente vamos começar a criar aplicações que interajam com a nossa rede, como obter configurações dos roteadores para backup, armazenar as mesmas em bancos de dados, detectar mudanças de configuração, fazer inventário etc etc..


Abçs
Jose CCIE#35681

Nenhum comentário:

Postar um comentário