Python 如何根据参数类型重载uuu init_uuuu方法?
假设我有一个类,它有一个名为data的成员,它是一个列表 我希望能够使用文件名(其中包含用于初始化列表的数据)或实际列表来初始化该类 你做这件事的技巧是什么 您是否只是通过查看Python 如何根据参数类型重载uuu init_uuuu方法?,python,constructor,operator-overloading,Python,Constructor,Operator Overloading,假设我有一个类,它有一个名为data的成员,它是一个列表 我希望能够使用文件名(其中包含用于初始化列表的数据)或实际列表来初始化该类 你做这件事的技巧是什么 您是否只是通过查看\uuuuu class\uuuuu来检查类型 有什么我可能错过的把戏吗 我习惯C++,其中参数类型重载很容易。 更好的方法是使用isinstance和类型转换。如果我对你的理解是正确的,你想要这个: def __init__ (self, filename): if isinstance (filename, b
\uuuuu class\uuuuu
来检查类型
有什么我可能错过的把戏吗
我习惯C++,其中参数类型重载很容易。 更好的方法是使用isinstance和类型转换。如果我对你的理解是正确的,你想要这个:
def __init__ (self, filename):
if isinstance (filename, basestring):
# filename is a string
else:
# try to convert to a list
self.path = list (filename)
更好的方法是使用isinstance和类型转换。如果我对你的理解是正确的,你想要这个:
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
内置函数:
self.data = data if isinstance(data, list) else self.parse(data)
你应该使用iInstance
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.).
你应该使用iInstance
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.).
好的,太好了。我只是用一个元组(而不是文件名)拼凑了这个例子,但这很简单。谢谢大家
class MyData:
def __init__(self, data):
self.myList = []
if isinstance(data, tuple):
for i in data:
self.myList.append(i)
else:
self.myList = data
def GetData(self):
print self.myList
a=[1,2]
b=(2,3)
c=我的数据(a)
d=我的数据(b)
c、 GetData()
d、 GetData()
[1,2]
[2,3]好的,太好了。我只是用一个元组(而不是文件名)拼凑了这个例子,但这很简单。谢谢大家
class MyData:
def __init__(self, data):
self.myList = []
if isinstance(data, tuple):
for i in data:
self.myList.append(i)
else:
self.myList = data
def GetData(self):
print self.myList
a=[1,2]
b=(2,3)
c=我的数据(a)
d=我的数据(b)
c、 GetData()
d、 GetData()
[1,2]
[2,3]获取“备用构造函数”的更简洁的方法是使用类方法。例如:
>>> 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')]
它更简洁的原因是,对于预期的数据类型没有疑问,并且您不会被迫猜测调用者打算让您如何处理它提供给您的数据类型。
isinstance(x,basestring)
的问题在于调用者无法告诉您,例如,即使类型不是basestring,您也应该将其视为字符串(而不是另一个序列)。而且调用者可能希望将同一类型用于不同的目的,有时作为单个项,有时作为一系列项目。明确化消除了所有疑问,并导致更健壮、更清晰的代码。获得“替代构造函数”的更简洁的方法是使用类方法。例如:
>>> 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')]
它更简洁的原因是,对于预期的数据类型没有疑问,并且您不会被迫猜测调用者打算让您如何处理它提供给您的数据类型。
isinstance(x,basestring)
的问题在于调用者无法告诉您,例如,即使类型不是basestring,您也应该将其视为字符串(而不是另一个序列)。而且调用者可能希望将同一类型用于不同的目的,有时作为单个项,有时作为一系列项目。明确的表达消除了所有的疑虑,并带来更健壮、更清晰的代码。非常好的问题。我也解决了这个问题,虽然我同意“工厂”(类方法构造函数)是一个很好的方法,但我想建议另一种方法,我也发现它非常有用:
下面是一个示例(这是一个read
方法,不是构造函数,但思想是一样的):
这里的关键思想是使用Python对命名参数的出色支持来实现这一点。现在,如果我想从文件中读取数据,我说:
obj.read(filename="blob.txt")
要从字符串中读取它,我说:
obj.read(str="\x34\x55")
这样,用户只需调用一个方法。正如您所看到的,在内部处理它并不是一个非常复杂的问题。我也解决了这个问题,虽然我同意“工厂”(类方法构造函数)是一个很好的方法,但我想建议另一种方法,我也发现它非常有用: 下面是一个示例(这是一个
read
方法,不是构造函数,但思想是一样的):
这里的关键思想是使用Python对命名参数的出色支持来实现这一点。现在,如果我想从文件中读取数据,我说:
obj.read(filename="blob.txt")
要从字符串中读取它,我说:
obj.read(str="\x34\x55")
这样,用户只需调用一个方法。正如您所看到的,在内部处理它并不是一件非常复杂的事,而是一个快速而肮脏的解决方案
class MyData:
def __init__(string=None,list=None):
if string is not None:
#do stuff
elif list is not None:
#do other stuff
else:
#make data empty
那你就可以用
MyData(astring)
MyData(None, alist)
MyData()
速战速决
class MyData:
def __init__(string=None,list=None):
if string is not None:
#do stuff
elif list is not None:
#do other stuff
else:
#make data empty
那你就可以用
MyData(astring)
MyData(None, alist)
MyData()
你为什么不更像蟒蛇呢?
你为什么不更像蟒蛇呢?
我的首选解决方案是:
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])
调用它
希望有帮助。快乐编码 我首选的解决方案是:
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])
调用它
希望有帮助。快乐编码 使用python3,您可以像Python食谱中所写的那样使用:
import time
class Date(metaclass=MultipleMeta):
def __init__(self, year:int, month:int, day:int):
self.year = year
self.month = month
self.day = day
def __init__(self):
t = time.localtime()
self.__init__(t.tm_year, t.tm_mon, t.tm_mday)
它的工作原理如下:
>>> d = Date(2012, 12, 21)
>>> d.year
2012
>>> e = Date()
>>> e.year
2018
使用python3,您可以使用Python Cookbook编写的:
import time
class Date(metaclass=MultipleMeta):
def __init__(self, year:int, month:int, day:int):
self.year = year
self.month = month
self.day = day
def __init__(self):
t = time.localtime()
self.__init__(t.tm_year, t.tm_mon, t.tm_mday)
它的工作原理如下:
>>> d = Date(2012, 12, 21)
>>> d.year
2012
>>> e = Date()
>>> e.year
2018
if-else表达式只在python 2.5(及更高版本)中可用if-else表达式只在python 2.5(及更高版本)中可用init中不需要所有这些代码——我将其缩短为一个类型转换,它做同样的事情并且更灵活。在python中,getter也基本上是不必要的。只需使用直接属性访问。如果需要做更多的工作,可以使用property()将getter/setter隐藏在普通属性访问之后;我只是想展示如何使用两种不同的输入类型。对于tuple/list可能不需要这样做,但如果这是一个文件名,就需要这样做。不过,我想这只是附和了其他人的说法。我的例子对我很有指导意义,因为在init中不需要所有的代码——我把它缩短为一个类型转换,它做同样的事情并且更灵活。在Python中,getter也基本上是不必要的。只需使用直接属性访问。如果需要做更多的工作,可以使用property()将getter/setter隐藏在普通属性访问之后