我是python的新手,但是我来自强大的C背景,我试图弄清楚它是如何工作的:How can I use a SOCKS 4/5 proxy with urllib2?
我无法理解的部分是它们覆盖socket.socket
但socket.socket
是一种'类型',就像运行type(socket.socket)
所说的那样。所以我对你如何能够覆盖这样的类型感到困惑,或者在这种情况下socket.socket
实际上是一个他们正在重新定义的函数,因此实际上返回了另一种类型?通常,如果我在函数上运行type
,则返回其函数或方法或其他内容。
我想我真正想要了解的是幕后发生了什么?
答案 0 :(得分:4)
我想我真正想要了解的是幕后发生了什么?
这是一个很好的问题。
将变量存储在另一个名称空间中,称为"monkey patching"。
代码示例实际上并没有覆盖类型。相反,它会更新套接字模块命名空间中的套接字变量,以指向socks 4/5类。然后,当 urllib2 查找 socket.socket 变量时,它现在使用SocksiPy module而不是本机套接字。
要知道的导入事项是 socket.socket 是一个最初设置为指向内置套接字类型的变量。可以更新该变量以指向新的4/5套接字类型。当 urllib2 查找变量时,它使用替换而不是原始。
从概念上讲,发生的事情大致类似于:
>>> socket = 'old_native_socket'
>>> def urllib2(url):
return 'Looking up', url, 'using', socket
>>> socket = 'new_4_5_socket'
>>> urllib2('http://www.python.org')
Looking up http://www.python.org using new_4_5_socket
以下是math模块的简单猴子补丁示例:
>>> import math
>>> def area(radius):
return math.pi * radius ** 2.0
>>> math.pi = 3.1 # monkey patch
>>> area(10)
310.0
答案 1 :(得分:1)
考虑以下
class SomeClass:
def __init__(self):
print "I am some class!"
class SomeOtherClass:
def __init__(self):
print "I am some other class!!"
c1 = SomeClass()
c2 = SomeOtherClass()
SomeClass = SomeOtherClass #shadows the other class
c3 = SomeClass()
这只是在模块级别socket