Interessante e utilidade do python. Parte 2

No artigo anterior, examinamos vários pontos interessantes da linguagem python, é claro, eles não estão limitados a um artigo, então continuaremos.

Um comentário examinou o seguinte código:

SEX = 'Female', 'Male' sex = SEX[True] # -> Male sex = SEX[False] # -> Female 

Funciona porque o tipo de dados lógicos é equivalente a 0 e 1, além disso, no início não havia um tipo especial e os valores 0 e 1. Foram utilizados e, quando inseridos, decidimos herdar do todo.

 print(int.__subclasses__()) # -> [<class 'bool'>] 

Mas voltando a obter os valores da lista, digamos que temos os seguintes dados:

 books = [["Sherlock Holmes", "Arthur Conan Doyle", 1986, True, 12.51], ["The Lost World", "Arthur Conan Doyle", 2015, False, 5.95], ["The Art of Computer Programming", "Donald E. Knuth ", 2017, True, 190.54] ] 

Obviamente, referir-se a valores por índices codificados permanentemente não é o nosso caminho. Você pode criar uma constante, por exemplo, AUTHOR e especificá-la, mas pode ir além:

 TITLE_AUTHOR = slice(0, 2) PRICE_IN_STOCK = slice(3, 5) print(books[0][TITLE_AUTHOR]) print([book for book in books if book[PRICE_IN_STOCK] > [True, 10.0]]) 

Podemos criar um objeto de fatia e indicar em quais índices os campos de interesse estão localizados. Podemos até ser corajosos o suficiente para escrever algo semelhante à última linha deste bloco, que exibe livros disponíveis no armazém e mais caros do que 10 qualquer coisa. Esse código funcionará, uma vez que a comparação de listas e tuplas ocorre lexicograficamente: primeiro os primeiros elementos são comparados, depois o segundo e assim por diante, ou seja, qualquer objeto cujo in_stock “campo” seja falso será menor que a lista [Verdadeiro, 10.0], pois Verdadeiro> Falso.

Nota: é claro que esse código não deve ser usado em projetos, mas é melhor limitar-se a obter apenas alguns valores para a fatia, é melhor fazer seleções no banco de dados, no Pandas ou como um método da classe Book. Você pode usar o namedtuple e escrever um pequeno módulo para colocar métodos com seleções semelhantes.

Já consideramos os argumentos que podem ser passados ​​para a função apenas por chave. Recentemente, enquanto estudava a documentação para a função bool , encontrei um subscrito:
Alterado na versão 3.7: x agora é um parâmetro apenas de posição.
Agora o PEP 570 está em desenvolvimento, o que abrirá a possibilidade de definir esses parâmetros. Isso pode ser útil quando o nome do parâmetro não importa, como bool (), pow () etc.

A sintaxe do rascunho é assim:

 def name(positional_only_parameters, /, positional_or_keyword_parameters, *, keyword_only_parameters): 

Retornando à função bool, que funciona como fazer check-in de condições e loops quando você executa o código

 if obj: #  while obj: 

O python executa um procedimento bastante interessante para gerar um valor booleano:

  1. Se o objeto implementar o método __bool __ (), o resultado da chamada desse método será retornado
  2. Caso contrário, é verificado se o método __len __ () está implementado; nesse caso, é verificado se ele retorna, se 0, o resultado será False.
  3. Se nenhum método for implementado, True será retornado.

 class A: pass a = A() print(bool(a)) # -> True 

Inteiros implementam o método __bool__, coleções padrão não o implementam, mas implementam o método __len__:

 print(dir(int)) # -> ['__abs__', '__add__', '__and__', '__bool__', '__ceil__', ... print(dir(list)) # -> ['__add__', '__class__', '__contains__', ... 

Em outro comentário , foi dado o comportamento "não-padrão" dos atributos de classe:

 class Example: arr=[] def __init__(self): pass a = Example() b = Example() a.arr.append(1) print(a.arr) # -> [1] print(b.arr) # -> [1] print(Example.arr) # -> [1] 

É muito importante distinguir entre os atributos de uma classe e um objeto ; os atributos de um objeto são criados, SUDDENLY, a partir do objeto.
É importante entender que quaisquer campos e métodos declarados no corpo da classe pertencem à classe. Para criar um atributo para um objeto, você precisa atribuí-lo ao objeto, no método de classe por meio de si mesmo ou no texto do programa, através da variável de objeto.

Se você ficar confuso, vamos analisar o código anterior, duas instâncias da classe são criadas nele, após as quais 1 é adicionada ao campo arr através de um dos objetos. Mas como não existe esse atributo no objeto, o construtor está vazio; portanto, o python procura esse atributo na classe e o encontra, no entanto, é compartilhado por todas as instâncias da classe. Você pode verificar se esse é o atributo da classe na última linha, pois o acesso à classe pelo nome desse atributo não gerou nenhum erro.

Ao aprender um novo idioma, é importante entender que cada idioma tem sua própria filosofia e nem todos os idiomas devem ter a palavra-chave estática. Às vezes, um mecanismo semelhante é fornecido por outros mecanismos.

Mais claramente, a ideia de que python não é java ilustra que a adição de campos em objetos e classes é feita através da atribuição usual:

 def make_title(self): if self.title == 'Mister': return 'Mr. ' + self.surname class Person: pass john = Person() john.title = 'Mister' john.name = 'John' john.surname = 'Peterson' john.age = 33 Person.make_title = make_title print(john.make_title()) 

Recomendação geral: não armazene tipos mutáveis ​​como instâncias de uma classe, isso é complicado, no entanto, se você sabe o que está fazendo, use essa funcionalidade ao máximo, o principal é pensar sobre tudo cuidadosamente no início e documentar depois.

Por exemplo, é muito simples criar uma classe que armazena links para todas as suas instâncias:

 class RememberAll(): instances = [] def __init__(self): self.instances.append(self) a = RememberAll() b = RememberAll() print(RememberAll.instances) #-> [<__main__.RememberAll object at 0x7faa4a5ab7b8>, <__main__.RememberAll object at 0x7faa4a523c88>] 

Você pode implementar a classe de algum objeto físico e, ao alterar suas características, chamar métodos para recalcular as características de outros elementos do sistema. Ou lembre-se de todos os controles deslizantes do formulário e, quando você mudar um, mova o resto automaticamente. Não presumo dizer que essa implementação seja sempre direta, mas às vezes pode ser útil.

Bem, desde que tocamos na física, quero mencionar o operador @. Sim, existe um . Foi introduzido para multiplicação de matrizes, o mais engraçado, mas parece que não foi implementado para nenhum dos tipos de dados padrão, ou seja, foi originalmente introduzido apenas para bibliotecas de terceiros. Mas nada impede que você inclua seu suporte para seus tipos de dados implementando os métodos __matmul__, __rmatmul__, __imatmul__

 class Person: def __init__(self, name): self.name = name def __matmul__(self, msg): return "@" + self.name + " " + msg john = Person("John") print(john @ "hello") # -> @John hello 

Source: https://habr.com/ru/post/pt422311/


All Articles