Ce qui a échoué lors du passage de Javaer à Pythonista

en premier

Ceci est l'article 12/2 du PyCon JP Advent Calendar 2016. Il y a d'autres articles intéressants, donc si vous êtes intéressé, faites-le. Il y a des endroits où Java est écrit, mais cela peut être faux car cela fait un moment, donc j'espère que vous pourrez le lire tout en observant l'atmosphère.

Objectif

Comme le sujet le dit, je vais partager les erreurs que j'ai commises afin que ceux qui liront ceci puissent faciliter la transition de Javaer à Pythonista.

Auto-introduction

Membre de PyCon JP 2017. À propos des activités liées à PyCon, Talk in 2015 et LT in 2016 / montre? v = O1-9Yv9cB8Q & t = 820s) J'ai également été conférencier au 1er Python Boot Camp. Le compte Twitter est @horobi_gengar

Histoire jusqu'à présent

En ce qui concerne le sujet, je pense que c'est nécessaire, je vais donc expliquer brièvement le langage utilisé dans le développement jusqu'à présent.

Commande Période d'inscription Langage principal Supplément
1ère entreprise Deux ans et demi rien de spécial c ou vb. Flexible selon le site
2ème entreprise 5 ans et demi Java En outre, JavaScript, Delphi, COBOL, etc.
3e entreprise 5 mois rien de spécial C#Et PHP petit à petit
4e entreprise 2 ans Python Très rarement impliqué dans Ruby
5ème entreprise 3 mois(En cours) Python Écrivez du JavaScript de temps en temps

Donc, cette histoire concerne la 4e entreprise.

Ce qui a échoué

J'ai écrit dans 1 fichier et 1 classe

J'ai fait beaucoup d'erreurs, mais c'était la plus grave. Java est essentiellement décrit dans un fichier et une classe (avec des exceptions), mais Python décrit souvent plusieurs classes dans un seul fichier. En termes d'image, Python doit être écrit avec une image qui a une hiérarchie de packages de moins que Java.

Je vais l'expliquer avec l'image du package (structure des dossiers). Par exemple, s'il s'agit de DAO pour accéder à la table des utilisateurs dans le module commun

common  └db   └dao

Créez un fichier appelé Users.java sous le package appelé Users et créez-y une classe appelée Users.

Et si vous souhaitez utiliser cette classe Users d'une autre classe,

Users.java


package common.db.dao.Users

users = new Users()
user = users.getUser(1)

C'est comme ressentir. Cependant, si vous écrivez en Python avec la même structure de package,

users.py


from common.db.dao.users import Users 

users = Users()
user = users.get_user(1)

Cela devient comme ça, et la fin de from et le contenu de l'importation sont superposés, ce qui est utile. Donc, dans ce cas, créez dao.py sous le package db, décrivez-y la classe Users et

users.py


from common.db.dao import Users 

users = Users()
user = users.get_user(1)

Doit être décrit comme. (Cela semble être un gros problème pour la taille du fichier dao, mais ce n'est qu'un exemple) En raison de cet échec, il a été décidé de modifier doucement un module qui avait un certain historique de fonctionnement.

J'ai rendu publiques toutes les variables internes.

Dans le cas de Java, si vous ajoutez public ou private au début de la variable interne de la classe, vous pouvez spécifier explicitement si elle peut être référencée de l'extérieur.

User.java



public class User{
    public int userId;          //Accessible de l'extérieur de la classe
    private String userName; //Inaccessible de l'extérieur de la classe
    public User(int userId, String userName){
        this.userId = userId
        this.userName = userName
  }
}

User u = new User(1, "Yamada Taro")
System.out.println(u.userId)  //sûr
System.out.println(u.userName)//en dehors

Par contre, dans le cas de Python, en ajoutant "_ (trait de soulignement)" au nom de la variable, il est possible de contrôler public et privé en Java. (Si vous voulez le faire, vous pouvez vous y référer.)

user.py


class User(object):
    def __init__(self, user_id, user_name):
        self.user_id = user_id       #Accessible de l'extérieur de la classe
        self.__user_name = user_name #Inaccessible de l'extérieur de la classe

u = User(1, 'Yamada Taro')
print(u.uer_id)     #sûr
print(u.__user_name)#en dehors

Donc, quand j'ai commencé à écrire Python, j'ai mal compris ce à quoi je pensais et je me suis souvenu des spécifications de langage suivantes.

user.py


class User(object):
    user_id = 0                    #Si vous l'écrivez à cet endroit, vous pouvez y accéder depuis l'extérieur de la classe
    def __init__(self, user_id, user_name):
        self.user_id = user_id       
        self.user_name = user_name #S'il n'est pas écrit, il sera traité comme privé

u = User(1, 'Yamada Taro')
print(u.uer_id)   #sûr
print(u.user_name)#en dehors(j'ai pensé)

Pourquoi est-ce arrivé? Bien sûr, user_name est accessible de l'extérieur autant que vous le souhaitez. Quand j'ai remarqué cela, de l'air froid a coulé sur mon dos et un festival avec deux barres inférieures devait avoir lieu.

J'ai fait un getter / setter.

Dans le cas de Java, ne spécifiez pas les variables internes comme publiques, mais créez des getters et des setters en tenant compte de la plage d'influence, etc.

User.java



public class User{
    private int userId;         //Gardez les variables internes inaccessibles de l'extérieur
    private String userName;
    public User(int userId, String userName){
        this.userId = userId
        this.userName = userName
    }
    public int getUserId(){
        return this.userId;
    }
    public int getUserName(){
        return this.userName;
    }
}

User u = new User(1, "Yamada Taro")
System.out.println(u.getUserId())  //Encapsuler en prenant en sandwich une fonction au lieu d'appeler directement une variable interne
System.out.println(u.getUserName())

Après tout, Eclipse a une fonction pour créer des getters et des setters en même temps. J'ai donc fait la même chose avec Python.

user.py



class User(object):
    def __init__(self, user_id, user_name):
        self.__user_id = user_id
        self.__user_name = user_name

    def get_user_id(self):
        return self.__user_id

    def get_user_name(self):
        return self.__user_name


u = User(1, 'Yamada Taro')
print(u.get_user_id())
print(u.get_user_name())#Utilisez-le comme ça

L'un des avantages des langages dits légers tels que Python est "une petite quantité de code". Cette mauvaise méthode de description est un très mauvais savoir-faire qui efface complètement ses mérites. Pardon. Dans le cas de Python, c'est très bien.

user.py



class User(object):
    def __init__(self, user_id, user_name):
        self.user_id = user_id       #Plus de barres inférieures si elles sont accessibles directement de l'extérieur
        self.user_name = user_name

u = User(1, 'Yamada Taro')
print(u.user_id)
u.user_name = 'Jiro Suzuki' #Vous pouvez y accéder autant que vous le souhaitez, mais c'est très bien! !! !!

Si cela vous tient vraiment à cœur, vous devriez également utiliser la propriété.

user.py



class User(object):
    def __init__(self, user_id, user_name):
        self.__user_id = user_id
        self.__user_name = user_name

    @property                          #S'il est en lecture seule, il ressemble à ceci
    def user_id(self):
        return self.__user_id

    @property
    def user_name(self):
        return self.__user_name


u = User(1, 'Yamada Taro')
print(u.user_id)       #sûr
u.user_name = 'Jiro Suzuki' #en dehors! !! !! !!

Il est important d'écrire correctement.

Épilogue

Plusieurs fois jusqu'à présent "Le Python que vous avez écrit est semblable à Java" "Je suis Javaer, mais le Python que vous avez écrit est facile à lire." On m'a dit que cela m'inquiétait beaucoup, alors j'ai écrit cet article. Après tout, comparé à Python écrit par quelqu'un qui a écrit d'autres langages légers pendant longtemps, le Python que j'ai écrit est un peu rigide et semblable à Java. J'écris Python depuis deux ans maintenant, donc je pense que l'odeur de Java a disparu, mais je continuerai à me consacrer chaque jour.

Recommended Posts

Ce qui a échoué lors du passage de Javaer à Pythonista
Ce que j'ai fait lors de la mise à jour de Python 2.6 vers 2.7
Que faire quand Ubuntu plante
Ce à quoi j'ai fait référence en étudiant tkinter
Points à noter lors du passage de NAOqi OS 2.4.3 à 2.5.5
Que faire quand une PermissionError dans tempfile.mkstemp se produit
Que faire si vous obtenez une erreur de mémoire lors de la conversion de PySparkDataFrame en PandasDataFrame
Somme de 1 à 10
curl: (60) Que faire lorsque le certificat de l'émetteur n'est pas valide.
Que faire lorsque gdal_merge génère un fichier énorme
Que faire lorsque vous déclenchez ValueError, "type de hachage non pris en charge"
Python - Remarques lors de la conversion du type str en type int
Accélération lors de la connexion de cx_Oracle à la base de données autonome
Que faire lorsque "impossible d'importer le nom xxx" [Python]
Ce à quoi j'étais accro lors de l'utilisation de Python tornado
Que faire lorsque vous obtenez une erreur indiquant «Échec temporaire de la résolution du nom» sous Linux