2017-05-08 5 views
-3

bar.py를 호출하는 foo.py 파일이 있습니다. Windows에서 Python 3.5.0을 사용합니다.Python은리스트의 참조 카운트를 증가시킵니다.

foo.py

def func(size = 100000): 
     myList = [5]*size 
     print(len(gc.get_referrers(myList))) #prints 1, gc is from gc module 
     size = testFunction_H.testFunction_API(myList) # control goes to bar.py 
     print(len(gc.get_referrers(myList))) #prints 2, why ? 
     del myList 

    testFunction_H = testFunction_API.init(); 

    for i in range(0, 30): 
     func(size=1000000) 

내가 bar.py.하는 foo.py에서 목록을 전달하고

This file has a class myClass whose below method is invoked from foo.py 

    def __call__(self, *args, **kwargs) 
    # args is a tuple that stores the passed list myList 
     print(len(gc.get_referrers(args))) #prints 1 
     future_tuple = self._myhandle.evaluateFunction(args) #evaluateFunction is a C++ function (in a .dll file) that I invoke from Python 
     print(len(gc.get_referrers(args)) #prints 1 
     return 5 #return some random value  

bar.py bar.py 내부에서 bar.py에 전달 된 목록의 참조 횟수가 1이고 갑자기 return 문을 통해 foo.py로 돌아 왔을 때 목록의 참조 횟수가 2임을 알 수 있습니다. evaluateFunction에 대한 호출을 주석 처리하면 "1 "도처에. 어떤 일이 벌어지고 있는지 설명 할 수 있습니까? 고맙습니다!

편집 : 나는 왜 이것이 부정적인 표를 얻는 지 이해하지 못합니다. 내가 가지고있는 문제는 상당히 복잡하고 그것을 재현하기 위해서는 추가 라이브러리가 필요하고 그렇지 않은 라이브러리가 필요합니다. 난 충분히 repro code를 scoped했고 "의미 론적"이슈를 발견하도록 요구하는 것은 부정 투표를받을 가치가 없다. bar.py에서

+1

은 아마도'evaluateFunction' 더 ... myList''에 대한 참조를 만드는 여기

행동에 참조 횟수 보여주는 작은 코드를 무엇입니까? –

+0

또한,'args'는리스트를 담고있는 * 튜플 (tuple *)이 될 것이기 때문에 그것이 보유하고있는 인수의 참조 카운트를 반영하지 않는 이유입니다. –

+4

이것은 실제 코드를 나타내지 않습니다. 우리는 이것을 실행할 수 없으며 이것을 디버깅 할 수 없습니다. – user2357112

답변

1

, * 인수이 튜플, 그래서 다음 코드는 당신에게 그 튜플에 대한 참조 수 있습니다 :

print(len(gc.get_referrers(args))) 

이 목록에 대한 참조의 수를 가지고가, 당신은 변경해야 에 : 당신이 목록에

print(len(gc.get_referrers(args[0]))) 

내가 @의 juanpa.arrivillaga에 동의, 당신의 evaluateFunction() 함수는 새로운 기준을 만드는 것입니다.

import gc 

def f(): 
    my_list = [5] 
    print("f #1: " + str(gc.get_referrers(my_list))) 
    g(my_list) 
    print("f #2: " + str(gc.get_referrers(my_list))) 

def g(*args): 
    print("g #1: " + str(gc.get_referrers(args))) 
    print("g #2: " + str(gc.get_referrers(args[0]))) 

f() 

당신이 얻을 :

f #1: [<frame object at 0x7fa82220dcc0>] 
g #1: [<frame object at 0x7fa8221fc218>] 
g #2: [<frame object at 0x7fa82220dcc0>, ([5],)] 
f #2: [<frame object at 0x7fa82220dcc0>] 
+0

Laurent LAPORTE와 juanpa.arrivillaga를 여러분의 의견에 대해 대단히 감사 드리며 초보 프로그래머를 바라보며 합리적인 질문에 대해 낙담하는 이기주의 엘리트 주의자처럼 행동하지 마십시오. 이 문제를 자세히 조사하는 데 도움이되었습니다. 다시 한번 감사드립니다! – Harry