Как исправить ошибку TypeError: expected string or bytes-like object?
Я написал регулярное выражение для проверки FQDN адресов, однако, оно не работает. Точно такое же регулярное выражение для ip-адресов выше проблем не создает. Я пытался приводить value словаря к строке в условии if/else, но это не помогло.
Полный текст ошибки:
Traceback (most recent call last):
File "c:\Users\kvvol\Desktop\Pytest\Script.py", line 72, in <module>
mistakes()
File "c:\Users\kvvol\Desktop\Pytest\Script.py", line 31, in mistakes
if(fqdnadd_pat.match(firewall['Исходящий FQDN']) and firewall['Исходящий FQDN'] != None):
TypeError: expected string or bytes-like object
Сам код:
import openpyxl
import re
wb = openpyxl.reader.excel.load_workbook(filename="Zayavka.xlsx")
wb.active = 0
ws = wb.active
firewall = {} #один блок с одним средством защиты
ipadd_pat = re.compile("^((([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/([1-9]|[1-2][0-9]|3[0-2]))?\s?(\([Nn][Aa][Tt]\s(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\))?;\s?){1,}$")
fqdnadd_pat = re.compile("^(([a-zA-Z0-9]+\.?)+\s?\(((([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]);\s?){1,}\);\s?){1,}$")
def mistakes():
if (firewall['Сегмент источника'] == firewall['Сегмент назначения']):
print('Сегмент источника и сегмент назначения совпадать не должны')
else:
if(firewall['Адрес/сеть назначения'] == None):
print('Заполните поле "Адрес/сеть назначения"')
if(firewall['Исходящий адрес'] != None):
print('Поле "Исходящий адрес" оставьте пустым')
elif(firewall['Исходящий IP-адрес/сеть'] == None and firewall['Исходящий адрес'] != None):
print('Содержимое поля "Исходящий адрес" перенесите в поле "Исходящий IP-адрес/сеть"')
if(ipadd_pat.match(firewall['Исходящий IP-адрес/сеть']) and firewall['Исходящий IP-адрес/сеть'] != None):
print("Ip-адреса заполнены корректно")
else:
print("Ip-адреса заполнены некорректно")
if(fqdnadd_pat.match(firewall['Исходящий FQDN']) and firewall['Исходящий FQDN'] != None): # на этой строке ошибка
print('FQDN заполнены корректно')
else:
print('FQDN заполнены некорректно')
if(firewall['Протокол доступа'] != None):
print('Поле "Протокол доступа" оставьте пустым')
if(firewall['Порт доступа'] != None):
print('Поле "Порт доступа" оставьте пустым')
def fire_fill():
firewall['Название средства защиты'] = ws['B' +str(i+1)].value
firewall['Сегмент источника'] = ws['B' +str(i+2)].value
firewall['Сегмент назначения'] = ws['B' +str(i+3)].value
firewall['Протокол доступа'] = ws['B' +str(i+4)].value
firewall['Исходящий адрес'] = ws['B' +str(i+5)].value
firewall['Порт доступа'] = ws['B' +str(i+6)].value
firewall['Исходящая учётная запись/AD'] = ws['B' +str(i+7)].value
firewall['Исходящий IP-адрес/сеть'] = ws['B' +str(i+8)].value
firewall['Исходящий FQDN'] = ws['B' +str(i+9)].value
firewall['Адрес/сеть назначения'] = ws['B' +str(i+10)].value
firewall['Адрес назначения FQDN'] = ws['B' +str(i+11)].value
firewall['Номер порта TCP'] = ws['B' +str(i+12)].value
firewall['Номер порта UDP'] = ws['B' +str(i+13)].value
for i in range(1, ws.max_row):
checker = i
if(ws['A' +str(i)].value == '№ Заявки'):
firewall['№ Заявки'] = ws['B' +str(i)].value
print()
print('Заявка ' + str(firewall['№ Заявки']))
block_counter = 1
while ws['A' +str(checker+1)].value == 'Название средства защиты':
fire_fill()
print()
print('Блок ' + str(block_counter))
mistakes()
checker += 12
block_counter += 1
Ответы (1 шт):
Конструкция condition1 and condition2 and condition3 выполняется в Python слева направо и если находится хотя бы одно условие для которого выполняется bool(conditionX) == False - проверка обрывается на этом месте и возвращается False. Все последующие условия не проверяются.
В вашем случае первым выполняется проверка fqdnadd_pat.match(firewall['Исходящий FQDN']), которая вызывает указанную в вопросе ошибку.
Поэтому вам надо изменить порядок проверки и кроме того лучше использовать идиоматический вид проверки на None:
if firewall.get('Исходящий FQDN') and fqdnadd_pat.match(firewall['Исходящий FQDN']):
...
if firewall.get('Исходящий FQDN') - делает сразу две проверки:
- проверка на существование в словаре
firewallключа"Исходящий FQDN", т.к.dict.get(<not-existing-key>)вернетNone - проверка на то, что значение firewall['Исходящий FQDN'] не
None
PS по канонам PEP-8, правильно проверять на variable is None следует так:
if not variable:
...
и для variable is not None:
if variable:
...