2013-03-18 1 views
1

우리가 실수로 같은 일부 시스템 라이브러리의 속성을 재정의합니다 코드의 버그 조각을 말해봐 :파이썬에서 시스템 라이브러리의 속성을 덮어 쓰지 않으려면 어떻게해야합니까?

import socket 
socket.error = 'some other object' 

이 문제를 방지하기 위해, 또는 그 일에 책임이있는 코드를 찾을 수있는 방법이 있나요?

나는 socket.error에서 속성을 시도하지만, 작동하지 않았다 :

def fget(self): 
    return socket.error 

def fset(self, value): 
    raise SystemError('You cannot alter this attribute.') 

# From now on, settings socket.error = x should raise an error 
socket.error = property(fget, fset) 
+1

를 얻을? '$ grep -r 'socket.error ='*' – danodonovan

+1

정말 프로덕션 코드에서는 거의 발생하지 않습니다. 일어날 때 당신은 충분히 빨리 알아낼 것이고 grep은 당신의 친구입니다. –

+1

grep이 (가) 아무것도 찾지 못했습니다. 장난 꾸러기 줄은 아마도'sock과 같은 import socket; x = '오류'; setattr (sock, x, 'some other object')' –

답변

6

당신은 (일시적으로) 코드에서이 스틱 수 :

class Bridge(object): 
    def __init__(self, module): 
     self.__dict__['module'] = module 
    def __getattr__(self, attr): 
     return getattr(self.module, attr) 
    def __setattr__(self, attr, val): 
     raise TypeError('{a!r} can not be set'.format(a=attr)) 

import sys 
import socket 
socket = sys.modules['socket'] = Bridge(socket) 

그런 설정 속성에 socket (적어도 가장 일반적인 방법으로) 예외가 발생합니다. 추적을 통해 오류를 찾을 수 있습니다.

print(socket.error) 
setattr(socket, 'error', 'blah') 

은 그냥 못된 줄을 grep을 할 수

% test.py 
<class 'socket.error'> 
Traceback (most recent call last): 
    File "/home/unutbu/pybin/test.py", line 15, in <module> 
    setattr(socket, 'error', 'blah') 
    File "/home/unutbu/pybin/test.py", line 10, in __setattr__ 
    raise TypeError('{a!r} can not be set'.format(a=attr)) 
TypeError: 'error' can not be set 
+2

다른 컴퓨터에서'import socket'을 실행하면 작동하지 않을 것입니다 filename 생성 된 브리지 대신 시스템 라이브러리가 표시됩니다. –

+0

@delnan - 정확하지만 sys.modules에는 Bridge 인스턴스에 대한 참조가 포함되지 않지만 시스템 라이브러리에 대한 참조가 포함됩니다. Bridge 인스턴스에 대한 실제 참조는 정의한 위치에서만 볼 수 있습니다. 아마도 또한 sys.modules에 집어 넣을 수 있을까요? –

+2

@MihneaGiurgea : 좋은 지적입니다. 'sys.modules [ 'socket'] = Bridge (socket)'를 설정하면이를 수정할 수 있습니다. – unutbu