파이썬에서 __str__에 대해 혼란스러워했습니다.
이 질문에는 이미 답변이 있습니다.
- Python __str__ 및 답변 9 개 나열
Java 배경에서 비롯된 것은 __str__
파이썬 버전의 toString과 비슷 하다는 것을 이해합니다 (Python이 이전 언어라는 것을 알고 있습니다).
그래서 __str__
다음과 같이 메소드 와 함께 작은 클래스를 정의했습니다 .
class Node:
def __init__(self, id):
self.id = id
self.neighbours = []
self.distance = 0
def __str__(self):
return str(self.id)
그런 다음 몇 가지 인스턴스를 만듭니다.
uno = Node(1)
due = Node(2)
tri = Node(3)
qua = Node(4)
이제 이러한 개체 중 하나를 인쇄하려고 할 때 예상되는 동작은 관련 값이 인쇄되는 것입니다. 이것도 발생합니다.
print uno
수확량
1
그러나 내가 다음을 할 때 :
uno.neighbours.append([[due, 4], [tri, 5]])
그리고
print uno.neighbours
나는 얻다
[[[<__main__.Node instance at 0x00000000023A6C48>, 4], [<__main__.Node instance at 0x00000000023A6D08>, 5]]]
내가 기대했던 곳
[[2, 4], [3, 5]]
내가 무엇을 놓치고 있습니까? 그리고 내가하고있는 다른 가치있는 물건은 무엇입니까? :)
파이썬은 객체를 문자열로 변환하는 두 가지 방법이 있습니다 : str()
and repr()
. 객체를 인쇄하는 데는 str()
; 개체를 포함하는 목록을 인쇄 str()
하면 목록 자체에 사용되지만 개별 항목에 대한 list.__str__()
호출 이 구현 repr()
됩니다.
따라서 덮어 써야합니다 __repr__()
. 간단한
__repr__ = __str__
수업이 끝나면 트릭을 수행합니다.
Java보다 Python의 무한한 우월성으로 인해 Python에는 1 개가 아닌 2 개의 toString 연산이 있습니다.
하나는 __str__
, 다른 하나는__repr__
__str__
사람이 읽을 수있는 문자열을 반환합니다. __repr__
내부 표현을 반환합니다.
__repr__
repr(obj)
backticks를 사용하거나 호출하여 객체에서 호출 할 수 있습니다 `obj`
.
When printing lists as well as other container classes, the contained elements will be printed using __repr__
.
It provides human readable version of output rather "Object": Example:
class Pet(object):
def __init__(self, name, species):
self.name = name
self.species = species
def getName(self):
return self.name
def getSpecies(self):
return self.species
def Norm(self):
return "%s is a %s" % (self.name, self.species)
if __name__=='__main__':
a = Pet("jax", "human")
print a
returns
<__main__.Pet object at 0x029E2F90>
while code with "str" return something different
class Pet(object):
def __init__(self, name, species):
self.name = name
self.species = species
def getName(self):
return self.name
def getSpecies(self):
return self.species
def __str__(self):
return "%s is a %s" % (self.name, self.species)
if __name__=='__main__':
a = Pet("jax", "human")
print a
returns:
jax is a human
Well, container objects' __str__
methods will use repr
on their contents, not str
. So you could use __repr__
instead of __str__
, seeing as you're using an ID as the result.
Answer to the question
As pointed out in another answer and as you can read in PEP 3140, str
on a list
calls for each item __repr__
. There is not much you can do about that part.
If you implement __repr__
, you will get something more descriptive, but if implemented correctly, not exactly what you expected.
Proper implementation
The fast, but wrong solution is to alias __repr__
to __str__
.
__repr__
should not be set to __str__
unconditionally. __repr__
should create a representation, that should look like a valid Python expression that could be used to recreate an object with the same value. In this case, this would rather be Node(2)
than 2
.
A proper implementation of __repr__
makes it possible to recreate the object. In this example, it should also contain the other significant members, like neighours
and distance
.
An incomplete example:
class Node:
def __init__(self, id, neighbours=[], distance=0):
self.id = id
self.neighbours = neighbours
self.distance = distance
def __str__(self):
return str(self.id)
def __repr__(self):
return "Node(id={0.id}, neighbours={0.neighbours!r}, distance={0.distance})".format(self)
# in an elaborate implementation, members that have the default
# value could be left out, but this would hide some information
uno = Node(1)
due = Node(2)
tri = Node(3)
qua = Node(4)
print uno
print str(uno)
print repr(uno)
uno.neighbours.append([[due, 4], [tri, 5]])
print uno
print uno.neighbours
print repr(uno)
Note: print repr(uno)
together with a proper implementation of __eq__
and __ne__
or __cmp__
would allow to recreate the object and check for equality.
__str__
is only called when a string representation is required of an object.
For example str(uno)
, print "%s" % uno
or print uno
However, there is another magic method called __repr__
this is the representation of an object. When you don't explicitly convert the object to a string, then the representation is used.
If you do this uno.neighbors.append([[str(due),4],[str(tri),5]])
it will do what you expect.
The thing about classes, and setting unencumbered global variables equal to some value within the class, is that what your global variable stores is actually the reference to the memory location the value is actually stored.
What you're seeing in your output is indicative of this.
Where you might be able to see the value and use print without issue on the initial global variables you used because of the str method and how print works, you won't be able to do this with lists, because what is stored in the elements within that list is just a reference to the memory location of the value -- read up on aliases, if you'd like to know more.
Additionally, when using lists and losing track of what is an alias and what is not, you might find you're changing the value of the original list element, if you change it in an alias list -- because again, when you set a list element equal to a list or element within a list, the new list only stores the reference to the memory location (it doesn't actually create new memory space specific to that new variable). This is where deepcopy comes in handy!
print self.id.__str__()
would work for you, although not that useful for you.
Your __str__
method will be more useful when you say want to print out a grid or struct representation as your program develops.
print self._grid.__str__()
def __str__(self):
"""
Return a string representation of the grid for debugging.
"""
grid_str = ""
for row in range(self._rows):
grid_str += str( self._grid[row] )
grid_str += '\n'
return grid_str
참고URL : https://stackoverflow.com/questions/12448175/confused-about-str-on-list-in-python
'programing tip' 카테고리의 다른 글
Microsoft Windows 용 터미널 멀티플렉서-GNU Screen 또는 tmux 용 설치 프로그램 (0) | 2020.07.27 |
---|---|
인식 할 수없는 속성 'targetFramework'. (0) | 2020.07.27 |
CSS-div를 포함하는 div의 아래쪽에 위치 div (0) | 2020.07.27 |
SQL- 문자열 검색 중 대소 문자 무시 (0) | 2020.07.27 |
오류 : 해당 속성 없음 : GROUP. 클래스 : org.gradle.api.publication.maven.internal.ant.DefaultGroovyMavenDeployer (0) | 2020.07.26 |