python kotlin_Java和Python中类似Kotlin的生成器,续:附加参数
python kotlin
介紹
在今天的文章中,我們將繼續上周的文章,內容涉及使用Java和Python創建類似Kotlin的構建器,并擴展了構建器API以采用一些可選參數以提高靈活性。 我們繼續我們HTML示例,嘗試添加標記屬性,例如class,id和style。
Kotlin和Python
Kotlin設置使用這些參數的方式與我在Python中的使用方式完全相同:默認參數和命名參數。 使用Kotlin看起來像這樣:
html {body {p(klass="myClass", id="theParagraph") {+ "the paragraph text"}} }請注意,使用“杯子”而不是“類”。 關鍵字和標識符的經典沖突。 您可以根據需要使用“ cls”,“ clazz”或其他任何東西。 我建議不要使用類對象語言中通常使用的任何東西,因為這是完全不同的類。
與上周的p標簽相比,這是一個很大的升級(只是p = "text" ),將其從屬性更改為成熟的方法。 但是大多數其他示例不需要太多工作。 這是更新的Kotlin代碼:
class Body {...fun p(class: String="", id: String="", style: Style=Style.blank, paragraphBuilder: Paragraph.() -> Unit) {val p = Paragraph(class, id, style)paragraphs.add(p)p.paragraphBuilder()}... }class Paragraph(val class: String, val id: String, val style: Style) {var text: String = ""operator fun plus(other: String) {text += other} }更新后的Python代碼(仍使用第一個版本)如下所示:
class Body:def __init__(self):self.paragraphs = ...def p(self, klass='', id='', style=None):par = Paragraph(klass, id, style)self.paragraphs.append(par)return parclass Paragraph:def __init__(self, klass, id, style):self.klass = klassself.id = idself.style = styleself.text = ''def __enter__(self):return selfdef __exit__(self, exc_type, exc_val, exc_tb):return Falsedef __iadd__(self, text):self.text += text__iadd__()是就地加法運算符,允許我們說p += 'text' 。 在Kotlin中,我們使用+而不是+=因為我們不必引用段落對象,因此從+=開頭看起來是錯誤的,而我們需要在Python代碼中引用p ,因此+=看起來更自然,這樣,我們就可以將調用代碼更改為以下形式:
html = Html() with html as html:with html.body() as body:with body.p(class='myClass', id='theParagraph') as p:p += 'the paragraph text'Kotlin和Python都采用Style對象,而不是像其他字符串一樣僅接受另一個字符串。 實際上,我建議也對class和id做同樣的事情,因為從那時起,我們將class和id對象及其CSS設置傳遞給CSS生成器。 我只是為了舉例而沒有在這里做。 我不讓Style保留字符串,因為最好使用某種CSS樣式生成器來提供更好的清晰度和正確性。
Java
Kotlin和Python都使過渡非常簡單。 不幸的是,Java沒有設置必需的功能來進行如此簡單的更改。 您必須依靠古老的流利的API技巧來使您理解它。
重載嘉豪!
首先想到的是盡可能多地進行帶有大量重載的轉換。 您可以為class和id字段創建快速,方便的字符串包裝器,因為它們都只是字符串,因此很難區分兩者:
class Class {public final String text;public Class(String text) {this.text = text;} }class ID {public final String text;public ID(String text) {this.text = text;} }這使得所有重載看起來像這樣:
class Body {...public void p(Consumer<Paragraph> paragraphBuilder) {...}public void p(Class klass, Consumer...) {...}public void p(ID id, Consumer...) {...}public void p(Style style, Consumer...) {...}public void p(Class klass, ID id, Consumer...) {...}// and so on... 3 more times... }這變得非常乏味,以至于我什至沒有寫完每一行,更不用說開始所有行了。 而且這僅考慮了類,id和樣式。 還有更多。 走這條路是不好的。 因此,我什至不會顯示結果代碼的樣子。 另外,對于其余的想法,我不會費心地展示API的實現,希望它是不言而喻的。 如果您真的對如何實現其中一種API感到好奇,請告訴我。
內部設定
設置這些屬性的另一種方法是在構建器中進行設置。 提供用于設置這些值的“ Paragraph方法。 在body標簽內看起來像這樣:
html.body(body -> {body.p(p -> { p.klass = "myClass"; p.id = "theParagraph";p.addText("the paragraph text");}); });這并不可怕(特別是在第一行上有那些設置程序行;將它們放在后續行上會混淆其目的),并且這可能是最簡單的,但是錯誤代碼的可能性會很高:
html.body(body -> {body.p(p -> {p.klass = "myClass";p.addText("the paragraph text");p.id = "theParagraph";}); });讓我們看看其他選項。
屬性對象
僅使用p()兩個重載(一個僅接受構建器函數的重載,以及一個既接受構建器函數又包含Attributes對象的重載),我們可以制作一個非常干凈的API,看起來像這樣:
html.body(body -> {body.p(Attributes.klass("myClass").id("theParagraph"), p -> {p.addText("the paragraph text");}); });就個人而言,這是我的最愛。 它需要更多的類和更多的實際復雜性,但是我覺得它是最可擴展的。 最大的不便是不同HTML標簽具有不同的屬性集。 可能應該有一個公共的Attributes構建器類,再加上一個特定于標記的類,從而使重載次數最多達到4(沒有屬性,只有基本的屬性,只有特定于標記的屬性,以及這兩種類型)。 四個重載是可以容忍的,但可能不應該。 如果看起來太多,最好堅持最后一種策略。
不過,為了完整起見,我還有一個,它實際上可能對其他不模仿HTML或XML的API更好地工作。
通話后大樓
最后一個想法是讓Body.p()返回Paragraph (最好是構建器的第二階段,因為這些方法可以在構建器lambda中使用,否則可以調用它們),如下所示:
html.body(body -> {body.p(p -> {p.addText("the paragraph text");}).klass("myClass").id("theParagraph"); });這實際上將Attributes類移到末尾,作為“ Paragraph構建器的第二階段。
奧托羅
那是我能給你的最好的。 如果您有興趣使用Java之類的語言來構建流暢的API,則應查閱jOOQ的文章,了解它們的用法 。 這是一種完全不考慮lambda的不同方式,這很好。 無論如何,下周我將發表一系列簡短的書評文章時,我將與你們交談。
翻譯自: https://www.javacodegeeks.com/2016/01/kotlin-like-builders-java-python-continued-additional-parameters.html
python kotlin
總結
以上是生活随笔為你收集整理的python kotlin_Java和Python中类似Kotlin的生成器,续:附加参数的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 电脑主板维修三包法多维(三包法两次维修)
- 下一篇: jooq_jOOQ星期二:拉斐尔·温特豪