Cet article ressemble à Lisp, mais pour le moment Python Part 2 Advent Calendar 2015 est l'article du troisième jour.
Dans la continuité de Dernière fois, nous explorerons la possibilité de Hy.
La version stable de Hy au moment de la rédaction de cet article est la 0.11.0.
Dans la version 0.11.0, lors de la définition d'une classe, utilisez def class
et écrivez comme suit.
(defclass FooBar [object]
[[--init--
(fn [self x]
(setv self.x x)
None)]
[get-x
(fn [self]
"Return our copy of x"
self.x)]])
Dans la dernière version de développement de Hy, comme documenté, comment définir une classe C'est un peu étrange.
(defclass FooBar [object]
(defn --init-- [self x]
(setv self.x x))
(defn get-x [self]
"Return our copy of x"
self.x))
Par rapport à la version 0.11.0 ou antérieure, le style d'écriture est plus propre.
Je ne sais pas quand la version qui peut être écrite sera stable, mais si elle change quand même, je m'habituerai à la nouvelle écriture, donc je suppose que je vais utiliser la version de développement de Hy installée à partir de github à partir de maintenant. écrire.
pip install git+https://github.com/hylang/hy.git
Cela n'a rien à voir avec la définition de la classe, mais quand j'écris un script pour vérifier l'opération,
if __name__ == '__main__':
#Faites quelque chose ici
func()
Je veux écrire un idiome équivalent à dans Hy.
Apparemment, «X» de Python devient «--X -» en Hy, vous pouvez donc l'écrire comme suit.
; hello.hy
(defn hello []
(print "Hello, World"))
(if (= --name-- "__main__")
(hello))
Exécutez avec l'interpréteur «hy».
$ hy ~/tmp/hello.hy
Hello, World
Quand j'ai pensé à l'exemple de la programmation orientée objet utilisant l'héritage de classe, je ne pouvais pas penser à un exemple utile, donc le chef-d'œuvre intemporel "Rudolph and Ippai Attena" J'ai fait un échantillon trivial basé sur dp / 4061335057 /).
Définissez la classe Cat
qui représente un chat domestique et le StrayCat
qui représente un chat errant en héritant de la classe abstraite ʻAbstractCat`.
; cat.hy
(defclass AbstractCat [object]
(defn --init-- [self name]
(setv self.name name))
(defn greet [self]
(raise NotImplementedError)))
(defclass StrayCat [AbstractCat]
(defn greet [self]
(.format "Mon nom est{}" self.name)))
(defclass Cat [AbstractCat]
(defn --init-- [self name home]
(.--init-- (super Cat self) name)
(setv self.home home))
(defn greet [self]
(.format "mon nom est{}。{}J'habite à." self.name self.home)))
(defn main []
(let [cat1 (Cat "Rudolph" "Maison de Rie-chan")
cat2 (StrayCat "Ippai Attena")]
(print (.greet cat1))
(print (.greet cat2))))
(if (= --name-- "__main__")
(main))
Simplement parce que «X» devient «--X -» donne l'impression que vous avez presque déplacé la syntaxe Python vers la syntaxe Lisp.
Le constructeur __init __
devient --init --
, et utilise(setv self.key value)
pour définir les propriétés.
(defclass AbstractCat [object]
(defn --init-- [self name]
(setv self.name name))
L'idiome Python super (X, self) .method ()
qui appelle la méthode de la classe parente est presque le même, juste remplacé par la syntaxe Lisp. Dans l'exemple ci-dessus, il est utilisé lors de l'appel du constructeur de la classe parent.
(defclass Cat [AbstractCat]
(defn --init-- [self name home]
(.--init-- (super Cat self) name)
(setv self.home home))
Le modèle qui lève une exception NotImplementedError
pour représenter une méthode abstraite peut être porté presque exactement comme (lever NotImplementedError)
.
(defclass AbstractCat [object]
;;Abréviation
(defn greet [self]
(raise NotImplementedError)))
Hy est livré avec un outil de conversion Hy → Python appelé hy2py
. Utilisons cet outil pour convertir l'exemple ci-dessus en code Python.
hy2py cat.hy
Le résultat est le suivant.
from hy.core.language import name
class AbstractCat(object):
def __init__(self, name):
self.name = name
self.name
return None
def greet(self):
raise NotImplementedError
class StrayCat(AbstractCat):
def greet(self):
return u'\u4ffa\u306e\u540d\u524d\u306f{}'.format(self.name)
class Cat(AbstractCat):
def __init__(self, name, home):
super(Cat, self).__init__(name)
self.home = home
self.home
return None
def greet(self):
return u'\u50d5\u306e\u540d\u524d\u306f{}\u3002{}\u306b\u4f4f\u3093\u3067\u3044\u307e\u3059\u3002'.format(self.name, self.home)
def main():
def _hy_anon_fn_6():
cat1 = Cat(u'\u30eb\u30c9\u30eb\u30d5', u'\u308a\u3048\u3061\u3083\u3093\u306e\u5bb6')
cat2 = StrayCat(u'\u30a4\u30c3\u30d1\u30a4\u30a2\u30c3\u30c6\u30ca')
(cat1, cat2)
print(cat1.greet())
return print(cat2.greet())
return _hy_anon_fn_6()
(main() if (__name__ == u'__main__') else None)
Il a été converti en code Python presque comme prévu, sauf qu'il contenait un "return None" sans signification.
Avec la dernière version de développement de Hy, vous pouvez définir des classes très intuitivement avec def class
, donc cela ne vous semble pas trop difficile.
Peut-être parce que la grammaire de Python est simple, le code Python et le code Hy se ressemblent beaucoup, et vous vous rendez compte que «tous les langages de programmation mènent à Lisp».
La prochaine fois, j'aimerais écrire un programme plus large pour explorer les possibilités de Hy.