Python类成员与特殊方法深度解析
本文深入解析Python类的成员访问机制,区分公有与私有成员的命名规则及继承限制。重点讲解类中特殊成员(魔术方法)的工作原理,包括__int__、__str__、__add__、__getitem__、__iter__等方法的自动触发条件与具体用法,结合代码示例说明对象转换、运算重载及迭代器实现细节。
类的成员在访问权限上主要分为两种形式。
公有成员具有广泛的访问权限,在类的内部、外部以及派生类中均可直接访问。
私有成员的访问受到严格限制,仅在定义该成员的类内部可见。在命名规范上,私有成员通常以两个下划线(__)作为前缀,例如__age。
class Foo:
def __init__(self, name, age):
self.name = name
self.__age = age
def show(self): # 间接方法私有字段
return self.__age
obj = Foo('klvchen', 25)
print(obj.name)
res = obj.show()
print(res)
运行结果:
klvchen 25
公有静态字段表现出较高的访问灵活性:类本身可以直接访问,类内部的方法可以访问,且派生类中也可以访问这些字段。
私有静态字段的访问权限较为严格,仅允许在定义该字段的类内部进行访问。
class Foo:
__v = '666' # 私有静态字段
def __init__(self):
pass
def show(self):
return Foo.__v
obj = Foo()
res = obj.show()
print(res)
运行结果:
666
class Foo:
__v = '666'
def __init__(self):
pass
def show(self):
return Foo.__v
@staticmethod
def stat():
return Foo.__v
res = Foo.stat()
print(res)
运行结果:
666
需要注意的是,私有字段无法从父类继承到子类中,子类无法直接访问父类的私有成员。
class F:
def __init__(self):
self.ge = 123
self.__gene = 456 #私有字段
class S(F):
def __init__(self, name):
self.name = name
self.__age = 18
super(S, self).__init__()
def show(self):
print(self.name)
print(self.__age)
print(self.ge)
print(self.__gene)
s = S('klvchen')
s.show()
运行结果:
klvchen 18 123 AttributeError: 'S' object has no attribute '_S__gene'
除了常规成员,类中还包含一系列特殊成员,通常被称为魔术方法(Magic Methods),它们以双下划线开头和结尾。
当执行类型转换操作时,Python会自动调用对象对应的特殊方法。例如,int(对象)会触发对象内部的__int__方法,并将返回值赋给int对象;同理,str(对象)会触发__str__方法,并将返回结果赋值给str对象。
class Foo:
def __init__(self):
pass
def __int__(self):
return 666
def __str__(self):
return 'hello world'
obj = Foo()
print(obj, type(obj))
res = int(obj)
print(res)
res1 = str(obj)
print(res1)
运行结果:
<__main__.Foo object at 0x0000022BBE9DA978> <class '__main__.Foo'> 666 hello world
当使用print(对象)或str(对象)时,Python解释器会自动执行对象类中定义的__str__方法,并返回该方法的结果。
class Foo:
def __init__(self, n, a):
self.name = n
self.age = a
def __str__(self):
return '%s-%d' %(self.name, self.age)
obj = Foo('klvchen', 28)
print(obj)
运行结果:
klvchen-28
在两个对象执行相加操作时,Python会自动执行第一个对象的__add__方法,并将第二个对象作为参数传递给该方法。
class Foo:
def __init__(self, name, age):
self.name = name
self.age = age
def __add__(self, other):
return self.age + other.age
obj1 = Foo('klv1', 23)
obj2 = Foo('klv2', 24)
res = obj1 + obj2
print(res, type(res))
运行结果:
47 <class 'int'> class Foo: def __init__(self, name, age): self.name = name self.age = age def __add__(self, other): return Foo(obj1.name, obj2.age) def __del__(self): print('析构方法') obj1 = Foo('klv1', 23) obj2 = Foo('klv2', 24) res = obj1 + obj2 print(res, type(res))
运行结果:
<__main__.Foo object at 0x0000016DFCE125C0> <class '__main__.Foo'> 析构方法 析构方法 析构方法
当对对象执行类似列表的索引操作(如li[对象])时,会自动执行该对象类中的__getitem__方法,并将方括号内的值(如8)作为参数传递给item。
class Foo:
def __init__(self, name, age):
self.name = name
self.age = age
def __getitem__(self, item):
return item
li = Foo('klvchen', 28)
r = li[8]
print(r)
运行结果:
8
类中还可以定义__setitem__和__delitem__方法,分别用于支持赋值操作和删除操作。
class Foo:
def __init__(self, name, age):
self.name = name
self.age = age
def __getitem__(self, item):
return item
def __setitem__(self, key, value):
print(key, value)
def __delitem__(self, key):
print(key)
li = Foo('klvchen', 28)
r = li[8]
print(r)
li[100] = 'hello'
del li[999]
运行结果:
8 100 hello 999
执行类中的__iter__()方法会获取其返回值,该返回值通常是一个迭代器对象。Python随后会循环调用该迭代器的next()方法(在Python 3中为__next__())。列表、字典、元组之所以支持for循环,正是因为它们的类型内部定义了__iter__方法以返回迭代器。
class Foo:
def __init__(self, name, age):
self.name = name
self.age = age
def __iter__(self):
return iter([11, 22, 33])
li = Foo('klvchen', 26)
for i in li:
print(i)
运行结果:
11 22 33
for循环的内部操作机制依赖于__iter__和__next__(或next)方法的配合。
obj = iter([11, 22, 33]) while True: val = obj.next() print val
总结
以上所述是小编给大家介绍的Python 类的特殊成员解析,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对本站网站的支持!
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













