假设我有一个类,它有一个成员叫做data,它是一个列表。
我希望能够初始化类,例如,一个文件名(包含初始化列表的数据)或一个实际的列表。
你的技巧是什么?
你只是通过查看__class__来检查类型吗?
我是不是漏掉了什么技巧?
我习惯了c++,在那里根据参数类型重载很容易。
假设我有一个类,它有一个成员叫做data,它是一个列表。
我希望能够初始化类,例如,一个文件名(包含初始化列表的数据)或一个实际的列表。
你的技巧是什么?
你只是通过查看__class__来检查类型吗?
我是不是漏掉了什么技巧?
我习惯了c++,在那里根据参数类型重载很容易。
当前回答
更好的方法是使用isinstance和type转换。如果我没理解错的话,你想要的是
def __init__ (self, filename):
if isinstance (filename, basestring):
# filename is a string
else:
# try to convert to a list
self.path = list (filename)
其他回答
你可能需要isinstance内置函数:
self.data = data if isinstance(data, list) else self.parse(data)
你应该使用isinstance
isinstance(...)
isinstance(object, class-or-type-or-tuple) -> bool
Return whether an object is an instance of a class or of a subclass thereof.
With a type as second argument, return whether that is the object's type.
The form using a tuple, isinstance(x, (A, B, ...)), is a shortcut for
isinstance(x, A) or isinstance(x, B) or ... (etc.).
更好的方法是使用isinstance和type转换。如果我没理解错的话,你想要的是
def __init__ (self, filename):
if isinstance (filename, basestring):
# filename is a string
else:
# try to convert to a list
self.path = list (filename)
获得“交替构造函数”的一个更简洁的方法是使用类方法。例如:
>>> class MyData:
... def __init__(self, data):
... "Initialize MyData from a sequence"
... self.data = data
...
... @classmethod
... def fromfilename(cls, filename):
... "Initialize MyData from a file"
... data = open(filename).readlines()
... return cls(data)
...
... @classmethod
... def fromdict(cls, datadict):
... "Initialize MyData from a dict's items"
... return cls(datadict.items())
...
>>> MyData([1, 2, 3]).data
[1, 2, 3]
>>> MyData.fromfilename("/tmp/foobar").data
['foo\n', 'bar\n', 'baz\n']
>>> MyData.fromdict({"spam": "ham"}).data
[('spam', 'ham')]
The reason it's neater is that there is no doubt about what type is expected, and you aren't forced to guess at what the caller intended for you to do with the datatype it gave you. The problem with isinstance(x, basestring) is that there is no way for the caller to tell you, for instance, that even though the type is not a basestring, you should treat it as a string (and not another sequence.) And perhaps the caller would like to use the same type for different purposes, sometimes as a single item, and sometimes as a sequence of items. Being explicit takes all doubt away and leads to more robust and clearer code.
我喜欢的解决方案是:
class MyClass:
_data = []
__init__(self,data=None):
# do init stuff
if not data: return
self._data = list(data) # list() copies the list, instead of pointing to it.
然后使用MyClass()或MyClass([1,2,3])调用它。
希望这能有所帮助。编码快乐!