web-dev-qa-db-fra.com

Comment casser une ligne de méthodes chaînées en Python?

J'ai une ligne du code suivant (ne blâmez pas les conventions de dénomination, elles ne sont pas les miennes):

subkeyword = Session.query(
    Subkeyword.subkeyword_id, Subkeyword.subkeyword_Word
).filter_by(
    subkeyword_company_id=self.e_company_id
).filter_by(
    subkeyword_Word=subkeyword_Word
).filter_by(
    subkeyword_active=True
).one()

Je n'aime pas à quoi ça ressemble (pas trop lisible) mais je n'ai pas de meilleure idée de limiter les lignes à 79 caractères dans cette situation. Existe-t-il un meilleur moyen de le casser (de préférence sans barre oblique inverse)?

123
Juliusz Gonera

Vous pouvez utiliser des parenthèses supplémentaires:

subkeyword = (
        Session.query(Subkeyword.subkeyword_id, Subkeyword.subkeyword_Word)
        .filter_by(subkeyword_company_id=self.e_company_id)
        .filter_by(subkeyword_Word=subkeyword_Word)
        .filter_by(subkeyword_active=True)
        .one()
    )
230
sth

Il s'agit d'un cas où un caractère de continuation de ligne est préférable aux parenthèses ouvertes. La nécessité de ce style devient plus évidente à mesure que les noms de méthode s'allongent et que les méthodes commencent à prendre des arguments:

subkeyword = Session.query(Subkeyword.subkeyword_id, Subkeyword.subkeyword_Word) \
                    .filter_by(subkeyword_company_id=self.e_company_id)          \
                    .filter_by(subkeyword_Word=subkeyword_Word)                  \
                    .filter_by(subkeyword_active=True)                           \
                    .one()

PEP 8 est destiné à être interprété avec une mesure de bon sens et un œil à la fois pratique et beau. Heureusement, violez toute directive PEP 8 qui entraîne un code laid ou difficile à lire.

Cela dit, si vous vous trouvez fréquemment en désaccord avec PEP 8, cela peut être un signe qu'il existe des problèmes de lisibilité qui transcendent votre choix d'espaces :-)

49

Mon choix personnel serait:

 subkeyword = Session.query (
 Subkeyword.subkeyword_id, 
 Subkeyword.subkeyword_Word, 
). filter_by (
 subkeyword_company_id = self.e_company_id, 
 subkeyword_Word = subkeyword_Word, 
 subkeyword_active = True, 
). one () 
13
pkoch

Il suffit de stocker le résultat/objet intermédiaire et d'appeler la méthode suivante dessus, par ex.

q = Session.query(Subkeyword.subkeyword_id, Subkeyword.subkeyword_Word)
q = q.filter_by(subkeyword_company_id=self.e_company_id)
q = q.filter_by(subkeyword_Word=subkeyword_Word)
q = q.filter_by(subkeyword_active=True)
subkeyword = q.one()
11
Ivo van der Wijk

C'est un peu une solution différente de celle fournie par d'autres mais un de mes favoris car cela conduit parfois à une métaprogrammation astucieuse.

base = [Subkeyword.subkeyword_id, Subkeyword_Word]
search = {
    'subkeyword_company_id':self.e_company_id,
    'subkeyword_Word':subkeyword_Word,
    'subkeyword_active':True,
    }
subkeyword = Session.query(*base).filter_by(**search).one()

C'est une belle technique pour construire des recherches. Parcourez une liste de conditions à extraire de votre formulaire de requête complexe (ou des déductions basées sur des chaînes sur ce que recherche l'utilisateur), puis explosez simplement le dictionnaire dans le filtre.

4

Selon Référence du langage Python
Vous pouvez utiliser une barre oblique inverse.
Ou tout simplement le casser. Si un crochet n'est pas apparié, python ne traitera pas cela comme une ligne. Et dans de telles circonstances, l'indentation des lignes suivantes n'a pas d'importance.

3
Haozhun

Vous semblez utiliser SQLAlchemy, si c'est vrai, la méthode sqlalchemy.orm.query.Query.filter_by() prend plusieurs arguments de mots clés, vous pouvez donc écrire comme:

subkeyword = Session.query(Subkeyword.subkeyword_id,
                           Subkeyword.subkeyword_Word) \
                    .filter_by(subkeyword_company_id=self.e_company_id,
                               subkeyword_Word=subkeyword_Word,
                               subkeyword_active=True) \
                    .one()

Mais ce serait mieux:

subkeyword = Session.query(Subkeyword.subkeyword_id,
                           Subkeyword.subkeyword_Word)
subkeyword = subkeyword.filter_by(subkeyword_company_id=self.e_company_id,
                                  subkeyword_Word=subkeyword_Word,
                                  subkeyword_active=True)
subkeuword = subkeyword.one()
1
minhee

J'aime mettre en retrait les arguments par deux blocs et la déclaration par un bloc, comme ceux-ci:

for image_pathname in image_directory.iterdir():
    image = cv2.imread(str(image_pathname))
    input_image = np.resize(
            image, (height, width, 3)
        ).transpose((2,0,1)).reshape(1, 3, height, width)
    net.forward_all(data=input_image)
    segmentation_index = net.blobs[
            'argmax'
        ].data.squeeze().transpose(1,2,0).astype(np.uint8)
    segmentation = np.empty(segmentation_index.shape, dtype=np.uint8)
    cv2.LUT(segmentation_index, label_colours, segmentation)
    prediction_pathname = prediction_directory / image_pathname.name
    cv2.imwrite(str(prediction_pathname), segmentation)
1
acgtyrant