- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我有一个将由客户端代码实现的“接口(interface)”:
class Runner:
def run(self):
pass
run
通常应该返回一个 docutils
node
但因为 far far most常见情况是纯文本,调用者允许 run
返回一个字符串,这将是使用 type()
检查并变成一个 node
。
但是,按照我对“Pythonic”的理解,这不是“Pythonic”,因为检查某物的 type()
不会让它通过“表现”而“成为”一种类型一——即“Pythonic”代码应该使用鸭子类型(duck typing)。
我考虑过
def run_str(self):
pass
def run_node(self):
return make_node(self.run_str())
但我不关心这个,因为它把不那么有趣的返回类型就在名字里;这让人分心。
有什么我错过的想法吗?另外,有没有我可能会遇到的问题在我的“坏”系统的道路上(对我来说似乎或多或少安全)?
最佳答案
我认为这是一个有点欺骗性的例子;有件事你没说。我猜当你说你“有一个接口(interface)”时,你的意思是你有一些代码接受一个对象并调用它的 run
方法。
如果您在调用对象的 run
方法之前没有测试该对象的类型,那么您就是在使用鸭子类型(duck typing),简单明了! (在这种情况下,如果它有一个 run
方法,那么它就是一个 Runner
。)只要你不使用 type
或 isinstance
在对象上使用 run
方法,那么你就是 Pythonic。
您是应该接受纯字符串还是只接受节点对象是一个略有不同的问题。字符串和 node
对象可能根本不实现相同的接口(interface)!从根本上说,字符串不会像节点
那样嘎嘎作响,因此您不必像对待一个节点那样对待它们。这就好比一头大象来了,要想它像鸭子类型(duck typing)一样嘎嘎叫,就得先给大象一个录音机,先训练大象使用它。
所以这不再是“鸭子类型(duck typing)”的问题,而是界面设计的问题。您正在尝试决定您希望界面的严格程度。
为了给你一个答案,那么,在这个层面上,我认为最 Pythonic 的假设是 run
返回一个 node
对象。无需使用 isinstance
或 type
对其进行测试。假设它是一个 node
对象,如果使用您的界面的程序员弄错了,并看到异常,那么他们将不得不阅读您的文档字符串,这将告诉他们 run
应该传递一个 node
对象。
然后,如果您想也接受字符串,或者像字符串一样嘎嘎作响的东西,您可以这样做。由于字符串是相当原始的类型,我认为使用 isinstance(obj, basestring)
并没有什么不合适的(但不是 type(obj) == str
因为它拒绝 unicode 字符串等)。从本质上讲,这是您对程序的懒惰用户非常慷慨和友善;你已经超越了接受大象以及像鸭子类型(duck typing)一样嘎嘎叫的东西。
(更具体地说,我想说这有点像在您想要同时接受生成器和序列的函数开头的参数上调用 iter
。)
关于python - 在这种情况下,如何平衡 "Pythonic"和 "convenient"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7102242/
这个问题在这里已经有了答案: What is the colon operator in Ruby? (9 个回答) 关闭 9 年前。 这是迄今为止我创建哈希的方式(根据 Codecademy) m
我一直收到这个错误,我不明白为什么。 error: delegating initializers in structs are not marked with 'convenience' 这就是我所
javadoc for NetworkInterface.getInetAddresses()说这是一个返回枚举的便捷方法,其中所有 InetAddress 或 InetAddress 的子集都绑定(
当你构建一个 Bazel 项目时,你的 WORKSPACE 项目根目录由一堆方便的符号链接(symbolic link)填充: /
我现在正在通过 iOS 编程 Big Nerd Ranch 一书学习 S.O.L.I.D。我想从 convenience init 创建一个数组,但我有一个问题,我想像数组的确切顺序一样显示文本和图像
我在 Xcode 中使用 Playground,但我的对象没有使用它们的名称进行初始化。我觉得这是因为我在我的子类中错误地使用了便利初始化,我想知道在子类中使用它们的正确方法是什么。我读过其他类似的问
这个问题在这里已经有了答案: Why convenience keyword is even needed in Swift? (6 个答案) 关闭 5 年前。 swift 中的 convenien
我正在使用 编写一个简单的秒表模板.由于这些函数在 std::chrono 中, 写成 using namespace std::chrono 会很方便以避免膨胀我的代码行。但由于它是一个模板,st
boost中的“header”和“convenience header”有什么区别? 最佳答案 便利 header 通常(不仅仅是在 Boost 中)是一个包含许多其他 header (包含实际代码)
是否有可能在 convenience init 中以某种方式解包可选 init? convenience init(...) { self.init?(...) ?? self.init() }
有没有什么方便的方法可以从文件名中删除任意扩展名,比如 bash ${i%%.*} ?我是否坚持我的 friend sed ? 最佳答案 如果您知道扩展名(例如 _bak,一个常见用例),这可能更方便
当实例方法返回使用便利构造函数初始化的值时,我是否需要保留该对象,然后在返回中自动释放,以便当便利构造函数的自动释放发生时,它不会删除该对象。 此释放描述会在调用代码之前进行,并通过保留或其他方式获取
我做了一个类: import UIKit class SearchBarItem: UIBarButtonItem { override convenience init() {
是否有 MonoTouch 内置方法来圆化 UIImage 的边缘? 好像记得看过一次。 最佳答案 舍入一个 UIImage 会产生另一个 UIImage。 如果您创建一个 CGContext 来渲染
使用 Sequelize 是否有性能优势,还是仅仅是为了方便?如果只是为了方便,我不明白。如果您希望它方便,为什么不只使用像 Mongo 这样的基于文档的数据库?如果要使用SQL,那我们就实际使用SQ
我有简单的类(class): class WmAttendee{ var mEmail:String! var mName:String! var mType:Int!
我有一个将由客户端代码实现的“接口(interface)”: class Runner: def run(self): pass run 通常应该返回一个 docutils n
我想用 gnuplot 放置几幅图通过以下方式: +------------------------+ |plot1 | |
我有一个问题,关于如何设计良好的 Nose 单元测试(使用每个测试事务和回滚),不仅围绕 SQLAlchemy 模型,而且围绕我编写的围绕 SQLAlchemy 模型创建的便利函数。 我对如何编写基本
何时使用 init、带参数的 init 或 iOS 8 (Swift) 中的便利 init, Objective-C 中的 convenience init 等价于什么? 最佳答案 你的类将有一个必需
我是一名优秀的程序员,十分优秀!