(阅读Alex的回答更新标题和内容)
总的来说,我认为函数根据其参数有时返回可迭代对象有时返回单个项目被认为是错误的形式(非 Pythonic)。
例如 struct.unpack 总是返回一个元组,即使它只包含一个项目。
我正在尝试完成一个模块的 API,我有一些函数可以采用一个或多个参数(通过 *args),如下所示:
a = s.read(10) # reads 10 bits and returns a single item
b, c = s.read(5, 5) # reads 5 bits twice and returns a list of two items.
所以如果只有一个参数,它返回一个项目,否则它返回一个列表。现在我认为这很好,一点也不令人困惑,但我怀疑其他人可能不同意。
这些函数最常见的用例是只希望返回一个项目,所以总是返回一个列表(或元组)感觉不对:
a, = s.read(10) # Prone to bugs when people forget to unpack the object
a = s.read(10)[0] # Ugly and it's not clear only one item is being returned
另一种选择是有两个函数:
a = s.read(10)
b, c = s.read_list(5, 5)
这没问题,但它会使 API 变得杂乱无章,并且需要用户记住两倍的函数而没有增加任何值(value)。
所以我的问题是: 有时返回一个可迭代的,有时返回一个单一的项目是否令人困惑和非 Pythonic?如果是这样,最好的选择是什么?
更新:我认为普遍的共识是,有时只返回一个可迭代对象是非常顽皮的。我认为大多数情况下的最佳选择是始终返回可迭代对象,即使它只包含一项。
话虽如此,对于我的特殊情况,我认为我将拆分为两个函数(read(item)/readlist(*items)),原因是我认为单个项目的情况会比多个项目的情况更频繁地发生,因此它更容易使用并且 API 更改对用户来说问题更少。
谢谢大家
最佳答案
如果您有时要返回迭代器,而在其他情况下返回单个对象,我会说总是返回一个迭代器,所以您不必考虑它。
通常,您会在需要迭代器的上下文中使用该函数,因此如果您必须检查它是否是要迭代的列表或只执行一次工作的对象,那么返回更容易一个迭代器并且总是迭代,即使它是一次。
如果返回一个元素后需要做一些不同的事情,只需使用 if len(var):。
请记住,一致性是一种宝贵的财富。
我倾向于返回一个一致的对象,不一定是同一类型,但如果我返回一个可迭代对象,我总是返回一个可迭代对象。
关于python - 函数根据其输入返回可迭代或不可迭代是 Pythonic 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1461392/
关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。
为什么4.1%2返回0.0999999999999996?但是4.2%2==0.2。 最佳答案 参见此处:WhatEveryProgrammerShouldKnowAboutFloating-PointArithmetic实数是无限的。计算机使用的位数有限(今天是32位、64位)。因此计算机进行的浮点运算不能代表所有的实数。0.1是这些数字之一。请注意,这不是与Ruby相关的问题,而是与所有编程语言相关的问题,因为它来自计算机表示实数的方式。 关于ruby-为什么4.1%2使用Ruby返
我想在一个没有Sass引擎的类中使用Sass颜色函数。我已经在项目中使用了sassgem,所以我认为搭载会像以下一样简单:classRectangleincludeSass::Script::FunctionsdefcolorSass::Script::Color.new([0x82,0x39,0x06])enddefrender#hamlengineexecutedwithcontextofself#sothatwithintemlateicouldcall#%stop{offset:'0%',stop:{color:lighten(color)}}endend更新:参见上面的#re
我正在尝试用ruby中的gsub函数替换字符串中的某些单词,但有时效果很好,在某些情况下会出现此错误?这种格式有什么问题吗NoMethodError(undefinedmethod`gsub!'fornil:NilClass):模型.rbclassTest"replacethisID1",WAY=>"replacethisID2andID3",DELTA=>"replacethisID4"}end另一个模型.rbclassCheck 最佳答案 啊,我找到了!gsub!是一个非常奇怪的方法。首先,它替换了字符串,所以它实际上修改了
我有一个用户工厂。我希望默认情况下确认用户。但是鉴于unconfirmed特征,我不希望它们被确认。虽然我有一个基于实现细节而不是抽象的工作实现,但我想知道如何正确地做到这一点。factory:userdoafter(:create)do|user,evaluator|#unwantedimplementationdetailshereunlessFactoryGirl.factories[:user].defined_traits.map(&:name).include?(:unconfirmed)user.confirm!endendtrait:unconfirmeddoenden
我有一个包含多个键的散列和一个字符串,该字符串不包含散列中的任何键或包含一个键。h={"k1"=>"v1","k2"=>"v2","k3"=>"v3"}s="thisisanexamplestringthatmightoccurwithakeysomewhereinthestringk1(withspecialcharacterslike(^&*$#@!^&&*))"检查s是否包含h中的任何键的最佳方法是什么,如果包含,则返回它包含的键的值?例如,对于上面的h和s的例子,输出应该是v1。编辑:只有字符串是用户定义的。哈希将始终相同。 最佳答案
我有一些代码在几个不同的位置之一运行:作为具有调试输出的命令行工具,作为不接受任何输出的更大程序的一部分,以及在Rails环境中。有时我需要根据代码的位置对代码进行细微的更改,我意识到以下样式似乎可行:print"Testingnestedfunctionsdefined\n"CLI=trueifCLIdeftest_printprint"CommandLineVersion\n"endelsedeftest_printprint"ReleaseVersion\n"endendtest_print()这导致:TestingnestedfunctionsdefinedCommandLin
我在用Ruby执行简单任务时遇到了一件奇怪的事情。我只想用每个方法迭代字母表,但迭代在执行中先进行:alfawit=("a".."z")puts"That'sanalphabet:\n\n#{alfawit.each{|litera|putslitera}}"这段代码的结果是:(缩写)abc⋮xyzThat'sanalphabet:a..z知道为什么它会这样工作或者我做错了什么吗?提前致谢。 最佳答案 因为您的each调用被插入到在固定字符串之前执行的字符串文字中。此外,each返回一个Enumerable,实际上您甚至打印它。试试
所以我开始关注ruby,很多东西看起来不错,但我对隐式return语句很反感。我理解默认情况下让所有内容返回self或nil但不是语句的最后一个值。对我来说,它看起来非常脆弱(尤其是)如果你正在使用一个不打算返回某些东西的方法(尤其是一个改变状态/破坏性方法的函数!),其他人可能最终依赖于一个返回对方法的目的并不重要,并且有很大的改变机会。隐式返回有什么意义?有没有办法让事情变得更简单?总是有返回以防止隐含返回被认为是好的做法吗?我是不是太担心这个了?附言当人们想要从方法中返回特定的东西时,他们是否经常使用隐式返回,这不是让你组中的其他人更容易破坏彼此的代码吗?当然,记录一切并给出
这个问题在这里已经有了答案:关闭10年前。PossibleDuplicate:Pythonconditionalassignmentoperator对于这样一个简单的问题表示歉意,但是谷歌搜索||=并不是很有帮助;)Python中是否有与Ruby和Perl中的||=语句等效的语句?例如:foo="hey"foo||="what"#assignfooifit'sundefined#fooisstill"hey"bar||="yeah"#baris"yeah"另外,类似这样的东西的通用术语是什么?条件分配是我的第一个猜测,但Wikipediapage跟我想的不太一样。