하는 방법에 과부하__init__방법에 따라 인수를 입력?
-
02-07-2019 - |
문제
가 하는 클래스가 구성원이라는 데이터 목록입니다.
할 수 있는 초기화 클래스로,예를 들어,파일명(을 포함하는 데이터를 초기화 목록)또는 실제 목록입니다.
당신의 기술에 대한 이것을 하고 있는가?
당신은 단지 확인하는 형식으로 보고 __class__
?
은 거기에 몇 가지게 될 수도 없는가?
내가 사용하는 C++는 오버로드에 의해 인수 유형은 쉽습니다.
해결책
매우 깔끔한 방법'대체 생성자를'사용하는 것입 classmethods.예를 들어:
>>> 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 처리해야 합 문자열로(그리고 다른다.) 그리고 아마도 발신자 같은 것을 사용하여 동일한 유형이 다른 목적으로,때로는 하나의 항목,때로는 일련의 항목입니다.되고 명시적인 모든 의심다도 더 강력하고 명확하게 코드입니다.
다른 팁
훌륭한 질문. 나는이 문제를 다루었 고, "공장"(클래스 메소드 생성자)이 좋은 방법이라는 데 동의하지만, 다른 것을 제안하고 싶습니다.
다음은 샘플입니다 (이것은 a입니다 read
생성자가 아니지만 아이디어는 동일합니다) :
def read(self, str=None, filename=None, addr=0):
""" Read binary data and return a store object. The data
store is also saved in the interal 'data' attribute.
The data can either be taken from a string (str
argument) or a file (provide a filename, which will
be read in binary mode). If both are provided, the str
will be used. If neither is provided, an ArgumentError
is raised.
"""
if str is None:
if filename is None:
raise ArgumentError('Please supply a string or a filename')
file = open(filename, 'rb')
str = file.read()
file.close()
...
... # rest of code
핵심 아이디어는 여기에 있다는 것입니다. 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()
더 좋은 방법은 Isinstance와 유형 변환을 사용하는 것입니다. 내가 당신을 올바르게 이해한다면, 당신은 이것을 원합니다 :
def __init__ (self, filename):
if isinstance (filename, basestring):
# filename is a string
else:
# try to convert to a list
self.path = list (filename)
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
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
내장 기능 :
self.data = data if isinstance(data, list) else self.parse(data)
내가 선호하는 솔루션은 다음과 같습니다.
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 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 = mydata (a)
d = mydata (b)
c.getData ()
d.getData ()
[1, 2]
[2, 3]
왜 더 피스닉에 가지 않습니까?
class AutoList:
def __init__(self, inp):
try: ## Assume an opened-file...
self.data = inp.read()
except AttributeError:
try: ## Assume an existent filename...
with open(inp, 'r') as fd:
self.data = fd.read()
except:
self.data = inp ## Who cares what that might be?