파이썬의 제네릭 / 템플릿?
파이썬은 제네릭 / 템플릿 유형 시나리오를 어떻게 처리합니까? "BinaryTree.py"외부 파일을 만들고 이진 트리를 처리하도록하고 싶지만 모든 데이터 유형에 대해 사용하고 싶다고 가정 해 보겠습니다.
그래서 사용자 지정 개체의 유형을 전달하고 해당 개체의 이진 트리를 가질 수 있습니다. 이것은 파이썬에서 어떻게 이루어 집니까?
파이썬은 덕 타이핑을 사용 하므로 여러 유형을 처리하기 위해 특별한 구문이 필요하지 않습니다.
C ++ 배경 인 경우 템플릿 함수 / 클래스에서 사용되는 작업이 특정 유형 T
(구문 수준에서) 에 정의되어 T
있는 한 템플릿에서 해당 유형 을 사용할 수 있다는 것을 기억할 것입니다 .
따라서 기본적으로 동일한 방식으로 작동합니다.
- 이진 트리에 삽입하려는 항목 유형에 대한 계약을 정의하십시오.
- 이 계약을 문서화하십시오 (즉, 클래스 문서에)
- 계약에 지정된 작업 만 사용하여 이진 트리 구현
- 즐겨
그러나 명시적인 유형 검사 (일반적으로 권장되지 않음)를 작성하지 않는 한 이진 트리에 선택한 유형의 요소 만 포함하도록 강제 할 수 없습니다.
실제로 이제 Python 3.5 이상에서 제네릭을 사용할 수 있습니다. PEP-484 및 입력 라이브러리 설명서를 참조하십시오 .
내 관행에 따르면 특히 Java Generics에 익숙하지만 여전히 사용 가능한 사람들에게는 매끄럽고 명확하지 않습니다.
파이썬으로 제네릭 타입을 만드는 것에 대한 좋은 생각을 떠난 후, 같은 생각을 가진 다른 사람들을 찾기 시작했지만 아무것도 찾을 수 없었습니다. 그래서 여기 있습니다. 나는 이것을 시도했고 잘 작동합니다. 파이썬에서 타입을 매개 변수화 할 수 있습니다.
class List( type ):
def __new__(type_ref, member_type):
class List(list):
def append(self, member):
if not isinstance(member, member_type):
raise TypeError('Attempted to append a "{0}" to a "{1}" which only takes a "{2}"'.format(
type(member).__name__,
type(self).__name__,
member_type.__name__
))
list.append(self, member)
return List
이제이 제네릭 유형에서 유형을 파생 할 수 있습니다.
class TestMember:
pass
class TestList(List(TestMember)):
def __init__(self):
super().__init__()
test_list = TestList()
test_list.append(TestMember())
test_list.append('test') # This line will raise an exception
이 솔루션은 단순하며 한계가 있습니다. 일반 유형을 작성할 때마다 새 유형이 작성됩니다. 따라서 List( str )
부모로 상속하는 여러 클래스 는 두 개의 개별 클래스에서 상속됩니다. 이를 극복하려면 내부 클래스의 다양한 형태를 저장하고 이전에 생성 된 내부 클래스를 반환하는 dict를 생성해야합니다. 이렇게하면 동일한 매개 변수가있는 중복 유형이 작성되지 않습니다. 관심이 있다면 데코레이터 및 / 또는 메타 클래스를 사용하여 더 우아한 솔루션을 만들 수 있습니다.
파이썬은 동적으로 입력되기 때문에 매우 쉽습니다. 사실, 어떤 데이터 유형과도 작동하지 않도록 BinaryTree 클래스에 대한 추가 작업을 수행해야합니다.
예를 들어, 객체를 key()
호출 하는 것과 같은 메서드에서 객체 내에서 사용 가능한 트리에 객체를 배치하는 데 사용되는 키 값을 원하는 경우 key()
입니다. 예를 들면 :
class BinaryTree(object):
def insert(self, object_to_insert):
key = object_to_insert.key()
object_to_insert 클래스의 종류를 정의 할 필요가 없습니다. 너무 오래 그것은이 같은 key()
방법을, 그것을 작동합니다.
예외는 문자열이나 정수와 같은 기본 데이터 유형으로 작업하려는 경우입니다. 일반 BinaryTree와 함께 작동하려면 클래스로 래핑해야합니다. 너무 무겁게 들리고 실제로 문자열을 저장하는 추가 효율성을 원한다면 죄송합니다. 파이썬이 잘하는 것은 아닙니다.
Python은 동적으로 유형이 지정되기 때문에 많은 경우 객체 유형이 중요하지 않습니다. 무엇이든 받아들이는 것이 더 좋은 생각입니다.
To demonstrate what I mean, this tree class will accept anything for its two branches:
class BinaryTree:
def __init__(self, left, right):
self.left, self.right = left, right
And it could be used like this:
branch1 = BinaryTree(1,2)
myitem = MyClass()
branch2 = BinaryTree(myitem, None)
tree = BinaryTree(branch1, branch2)
Look at how the built-in containers do it. dict
and list
and so on contain heterogeneous elements of whatever types you like. If you define, say, an insert(val)
function for your tree, it will at some point do something like node.value = val
and Python will take care of the rest.
Fortunately there has been some efforts for the generic programming in python . There is a library : generic
Here is the documentation for it: http://generic.readthedocs.org/en/latest/
It hasn't progress over years , but you can have a rough idea how to use & make your own library.
Cheers
If you using Python 2 or want to rewrite java code. Their is not real solution for this. Here is what I get working in a night: https://github.com/FlorianSteenbuck/python-generics I still get no compiler so you currently using it like that:
class A(GenericObject):
def __init__(self, *args, **kwargs):
GenericObject.__init__(self, [
['b',extends,int],
['a',extends,str],
[0,extends,bool],
['T',extends,float]
], *args, **kwargs)
def _init(self, c, a, b):
print "success c="+str(c)+" a="+str(a)+" b="+str(b)
TODOs
- Compiler
- Get Generic Classes and Types working (For things like
<? extends List<Number>>
) - Add
super
support - Add
?
support - Code Clean Up
참고URL : https://stackoverflow.com/questions/6725868/generics-templates-in-python
'developer tip' 카테고리의 다른 글
x86 어셈블리에서 leave가 "mov esp, ebp"를 수행하는 이유는 무엇입니까? (0) | 2020.11.28 |
---|---|
HTML5 속성을 인용합니까? (0) | 2020.11.28 |
파이썬에서 float에 대한 내장 pow ()와 math.pow ()의 차이점은 무엇입니까? (0) | 2020.11.28 |
템플릿을 사용하여 람다를 std :: function으로 변환하는 방법 (0) | 2020.11.28 |
.svn 폴더 크기 줄이기 (0) | 2020.11.28 |