Solucionado (ver solução)
Solucionado
(ver solução)
2
respostas

[Dúvida] Dúvida - Não foi possível usar o upper() em usuario.profissao para o caso desta variável não ser informada (None). (Mensagem de erro: AttributeError: 'NoneType' object has no attribute 'upper')

print("POO \n Capítulo 03. Property e métodos de classes.\n Item 06: Mão na massa: refatorando uma função")
class Pessoa:
    #Método construtor
    cadastro_pessoas=[]
    def __init__(usuario, _nome="", _profissao="", _idade=0) -> None:
        usuario._nome= _nome.upper()       
        usuario._profissao = _profissao
        usuario._idade =  _idade
        Pessoa.cadastro_pessoas.append(usuario)

    #Método especial str
    def _str_(usuario):
        try:
            return f"USUÁRIO: {usuario._nome} | PROFISSÃO: {usuario._profissao} | IDADE: {usuario._idade}"
        except:
            return f"USUÁRIO: {usuario._nome} | PROFISSÃO: {usuario._profissao}"
        else:
            return f"USUÁRIO: {usuario._nome} | IDADE: {usuario._idade}"

    # O @property permite que a função seja acessada como um atributo sem parênteses (usuario1.saudacao)
    @property
    # Propriedade saudação
    def saudacao(usuario):
        return f"OLÁ {usuario._nome}, SUA PROFISSÃO CADASTRADA É {usuario._profissao} E SUA IDADE CADASTRADA É {usuario._idade} anos."
    
    #Método de instância aniversário (Um método em uma classe precisa ser chamado com parênteses para ser executado). usuario3.aniversario()

    def aniversario(usuario):
        usuario._idade+=1
        return usuario._idade
    
    #Teste

usuario1=Pessoa("wiliam da silva", "analista ambiental", 40)
usuario2=Pessoa("elias da silva", "pedreiro", 60)
usuario3=Pessoa("julio da silva", "futebolista", 30)
usuario4=Pessoa("cesar da silva", None , 31)
usuario5=Pessoa("gomes da silva", "motorista", None)

print(usuario1.saudacao)
print(usuario2._nome.ljust(20), usuario2._profissao.ljust(20), usuario2._idade)
print(usuario3._str_())
print(usuario3.aniversario())
print(usuario4._str_())
print(usuario5._str_())
2 respostas
solução!

Bom dia Estudante! Tudo bem com você?

Para resolver o erro atributo (AttributeError) ao tentar usar o método upper() em uma variável que pode serNone, podemos utilizar uma verificação condicional para assegurar que só seja aplicado o método upper() se a variável não for None. Como no código apresentado abaixo:

if _profissao:
    usuario._profissao = _profissao.upper()
else:
    usuario._profissao = None

O código acima verifica se o atributo profissão foi informado (if _profissao) caso tenha sido informado, o método upper() é chamado, caso seja None, não será chamado o método upper() e será atribuído o valor None a variável _profissao. Aplicando o código no método construtor ficará da seguinte forma:

def __init__(usuario, _nome="", _profissao="", _idade=0) -> None:
        
        if _nome:
            usuario._nome = _nome.upper()
        else:
            usuario._nome = None    
        
        if _profissao:
            usuario._profissao = _profissao.upper()
        else:
            usuario._profissao = None

        usuario._idade =  _idade
        Pessoa.cadastro_pessoas.append(usuario)

Na imagem abaixo apresento o resultado após as modificações recomendadas, note o valor do campo profissão como "None".

Imagem apresentado o resultado da execução do código do aluno após modificações sugeridas

Após realizar as modificações acima, salve o arquivo e execute-o novamente.

Para saber mais: Existe uma outra forma mais elegante que podemos implementar a verificação condicional, será utilizando uma expressão ternária que possui a seguinte sintaxe:

o_quero_fazer if se_esse_for_verdadeiro else faço_esse_se_for_falso

Aplicando no seu código:

usuario._profissao = _profissao.upper() if _profissao else None

No código acima, queremos chamar a função upper() se _profissao for verdadeiro caso não seja atribuímos None. Aplicando esse conceito no construtor teremos o seguinte código:

    def __init__(usuario, _nome="", _profissao="", _idade=0) -> None:
        usuario._nome = _nome.upper() if _nome else None       
        usuario._profissao = _profissao.upper() if _profissao else None
        usuario._idade =  _idade
        Pessoa.cadastro_pessoas.append(usuario)

Note que o código ficou mais enxuto. Caso queira aprofundar ainda mais no conhecimento sobre este assunto, recomendo a leitura deste artigom Operadores ternários em Python, que aborda sobre a utilização dos operadores ternários em Python para simplificar e encurtar as condições if/else em uma única linha de código, destacando suas vantagens em termos de simplicidade e versatilidade.

Espero ter ajudado. Conte com o apoio do Fórum na sua jornada. Fico à disposição. Abraços e bons estudos!

Caso este post tenha lhe ajudado, por favor, marcar como solucionado ✓. Bons Estudos!

Muito obrigado Rafael. Irei ler o Artigo recomendado.