检查给定对象是否属于给定类型的最佳方法是什么?如何检查对象是否继承给定类型?
假设我有一个对象o.我如何检查它是否是一个str?
assert作为标准代码的一部分使用而不是仅仅用于调试目的,是否存在性能或代码维护问题?
是
assert x >= 0, 'x is less than zero'
Run Code Online (Sandbox Code Playgroud)
好或坏比
if x < 0:
raise Exception, 'x is less than zero'
Run Code Online (Sandbox Code Playgroud)另外,有没有办法设置业务规则if x < 0 raise error,总是在没有try/except/finally这样的情况下进行检查,如果在整个代码中的任何时候x小于0都会引发错误,就像你assert x < 0在函数的开头设置一样,在函数内的任何地方哪里x变得少于0则引发异常?
有没有办法获取类实例上存在的属性列表?
class new_class():
def __init__(self, number):
self.multi = int(number) * 2
self.str = str(number)
a = new_class(2)
print(', '.join(a.SOMETHING))
Run Code Online (Sandbox Code Playgroud)
期望的结果是将输出"multi,str".我希望这能看到脚本各个部分的当前属性.
如果我想使用一个需要字典或类似映射的对象的方法(参见collections.Mapping)来使用argparse.ArgumentParser()作为Namespace对象的结果,那么正确的方法是什么?
C:\>python
Python 2.7.3 (default, Apr 10 2012, 23:31:26) [MSC v.1500 32 bit (Intel)] on win
32
Type "help", "copyright", "credits" or "license" for more information.
>>> import argparse
>>> args = argparse.Namespace()
>>> args.foo = 1
>>> args.bar = [1,2,3]
>>> args.baz = 'yippee'
>>> args['baz']
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'Namespace' object has no attribute '__getitem__'
>>> dir(args)
['__class__', '__contains__', '__delattr__', '__dict__', '__doc__', '__eq__', '_ …Run Code Online (Sandbox Code Playgroud) if hasattr(obj, 'attribute'):
# do somthing
Run Code Online (Sandbox Code Playgroud)
VS
try:
# access obj.attribute
except AttributeError, e:
# deal with AttributeError
Run Code Online (Sandbox Code Playgroud)
哪个应该是首选,为什么?
哪种方法可以检查属性是否存在?
Jarret Hardie提供了这个答案:
if hasattr(a, 'property'):
a.property
Run Code Online (Sandbox Code Playgroud)
我看到它也可以这样做:
if 'property' in a.__dict__:
a.property
Run Code Online (Sandbox Code Playgroud)
一种方法通常比其他方法更常用吗?
我正在使用一些使用该socket.fromfd()函数的Python套接字代码.
但是,此方法并非在所有平台上都可用,因此在未定义方法的情况下,我正在编写一些回退代码.
确定方法是否在运行时定义的最佳方法是什么?以下是否足够或有更好的成语?
if 'fromfd' in dir(socket):
sock = socket.fromfd(...)
else:
sock = socket.socket(...)
Run Code Online (Sandbox Code Playgroud)
我有点担心文档dir()似乎不鼓励使用它.将getattr()是一个更好的选择,如:
if getattr(socket, 'fromfd', None) is not None:
sock = socket.fromfd(...)
else:
sock = socket.socket(...)
Run Code Online (Sandbox Code Playgroud)
思考?
编辑正如Paolo所指出的,这个问题几乎与确定属性存在的问题重复.但是,由于使用的术语是不相交的(lk的"对象有一个属性" vs我的"模块有一个函数"),保留这个问题以获得可搜索性可能会有所帮助,除非两者可以组合.
在 JavaScript 中,如果我不确定链中的每个元素是否存在/不是未定义,我可以做foo?.bar,如果bar不存在foo,解释器将悄悄地短路它而不抛出错误。
Python中有没有类似的东西?目前,我一直这样做:
if foo and foo.bar and foo.bar.baz:
# do something
Run Code Online (Sandbox Code Playgroud)
我的直觉告诉我,这不是检查链中每个元素是否存在的最佳方法。有没有更优雅/Pythonic 的方式来做到这一点?
在Python中,iterable的接口是迭代器接口的子集.这具有的优点是,在许多情况下,它们可以以相同的方式处理.但是,两者之间存在重要的语义差异,因为对于iterable,__iter__返回一个新的迭代器对象而不仅仅是self.我怎样才能测试一个iterable真的是一个可迭代的而不是一个迭代器?从概念上讲,我理解iterables是集合,而迭代器只管理迭代(即跟踪位置)但不是集合本身.
当想要多次循环时,差异是重要的.如果给出了迭代器,则第二个循环将不起作用,因为迭代器已经用完并直接引发StopIteration.
测试一种next方法很有吸引力,但这看起来很危险而且有些不对.我应该检查第二个循环是否为空?
有没有办法以更加pythonic的方式进行这样的测试?我知道这听起来像是针对EAFP的LBYL的经典案例,所以也许我应该放弃?或者我错过了什么?
编辑: S.Lott在下面的回答中说,这主要是想要在迭代器上进行多次传递的问题,并且首先不应该这样做.但是,在我的情况下,数据非常大,并且根据情况必须多次传递以进行数据处理(绝对没有办法解决这个问题).
迭代也由用户提供,并且对于单次传递足够的情况,它将与迭代器一起工作(例如,为了简单起见,由生成器创建).但是,如果用户在需要多次传递时只提供迭代器,那么防止这种情况会很好.
编辑2:
实际上这是一个非常好的抽象基类的例子.将__iter__在迭代器和迭代方法具有相同的名称,但语义上是不同的!所以hasattr没用,但isinstance提供了一个干净的解决方案.
我试图在一般函数中获取文档属性,但是一些模型可能没有文档属性.有没有办法首先检查模型是否具有documents属性,然后有条件地运行代码?
if self.model has property documents:
context['documents'] = self.get_object().documents.()
Run Code Online (Sandbox Code Playgroud) python ×10
attributes ×2
python-3.x ×2
assert ×1
assertion ×1
class ×1
dictionary ×1
django ×1
duck-typing ×1
exception ×1
hasattr ×1
iterator ×1
raise ×1
types ×1