Python中的名称混淆
Python中实现名称混淆过程的方式与我们上面讨论的一样。我们将在Python程序中使用不同的方法来实现名称混淆过程并访问其中的变量。
在本节中,我们将执行以下任务:
- 使用dir()方法在Python中进行名称混淆
- 在程序中访问名称混淆的变量
- 在Python中使用方法重写来实现名称混淆
我们将为每种方法使用一个程序来了解其在Python中的实现。
1. 使用dir()方法进行名称混淆
我们可以使用dir()方法来执行名称混淆过程,并将其应用于代码中给定的类。 Python解释器将对该类执行名称混淆过程。我们可以通过将定义的类对象传递给dir()方法来使用dir()方法,并且dir()方法将返回属于给定类对象的所有有效属性。
查看以下示例程序,了解这个name mangling的dir()方法:
示例:
# 一个用于name mangling的测试类
class Testing:
def __init__(self, name):
self.__name = name
# 用测试类初始化变量
t1 = Testing("JavaTpoint")
# 在初始化的变量上使用dir()方法
print(dir(t1))
输出:
['_Testing__name', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__']
说明:
当我们看到输出时,我们可以看到我们在初始化的变量(即t1)上使用的dir()方法返回了类testing的所有有效属性并打印出它们。我们还可以看到,标识符__name(即名称)被解释器更改为_Testing__name。
2. 访问名称混淆变量
我们甚至可以在类之外访问名称混淆变量并将其打印出来(与访问类变量不同,访问类变量会返回错误)。要在类之外访问名称混淆变量,我们只需将变量后面添加_ClassName,然后我们还可以将值打印出来。
看下面的程序,我们在testing类之外访问了名称混淆变量。
示例:
# 一个用于名称混淆的测试类
class Testing:
def __init__(self, name):
self.__name = name
# 使用测试类初始化变量
t1 = Testing("JavaTpoint")
# 在测试类外部访问名称混淆变量
print("我们在类外部访问的名称混淆变量: ", t1._Testing__name)
输出:
我们在类外部访问的名称混淆变量: JavaTpoint
解释:
因为__name是一个名称混淆变量,所以我们能够在外部访问它,并且它在输出中返回了名称的值。
3. 使用方法覆盖进行名称混淆
由于我们在程序中使用了名称混淆过程,所以我们受到了对私有类成员的有效使用的限制。对于私有类成员的有效使用场景的有限支持是为了避免与子类内定义的各种名称发生冲突。只要名称混淆过程按照Python类的定义进行,解释器就会执行混淆过程。对于程序中的子类来说,这非常有帮助,因为它们可以在不破坏类间方法调用的情况下重写方法。
让我们理解以下示例。
示例:
# 默认用于名称重整的测试类
class Testing:
def __init__(self):
self.__jtp() # 使用Jtp变量进行名称重整
def jtp(self): # 父类中用于名称重整的默认函数
print("在父测试类内完成名称重整过程")
# 私有类成员的jtp()方法副本
__jtp = jtp # 使用方法重写过程的名称重整
# 用于Testing类的子类
class SubTesting(Testing):
# 为jtp()函数提供新的标记
def jtp(self):
print("在子子测试类内完成名称重整过程")
# 调用子类的对象和其函数
obj = SubTesting()
obj.jtp()
输出:
在父类的测试类内进行名称修饰过程
在子测试类内进行名称修饰过程
结论
首先,我们在本教程中了解了名称修饰过程的介绍。我们还学习了如何在Python中使用 dir() 方法进行名称修饰。然后,我们访问了类外部存在的名称修饰的变量。最后,我们还学习了如何在程序中的给定子类中使用方法覆盖的名称修饰过程。