声明:本内容非盈利性质,也不支持任何组织或个人将其用作盈利用途。本内容来源于参考书或网站,会尽量附上原文链接,并鼓励大家看原文。侵删。
2.7 匿名类与内部类
2.7.1 匿名类
python中的匿名类就是不需要类名,在使用时直接创建为一个实例化对象的类。
python中有两种方式可以很灵活地实现匿名类的效果:namedtuple(名称元组)和type()函数。
(1)使用namedtuple创建纯属性的匿名类
namedtuple是python的collections中定义的一种高级元组数据结构,它由namedtuple()函数实现(后面会详细学习这种数据结构)。如下:
from collections import namedtuple # 导包
obj1 = namedtuple("variables", ['foo', 'woo', 'boo'])(foo=1, woo=2, boo='3') # 创建包含有三个属性'foo', 'woo', 'boo'的名称元组,并为其赋值,这个名称元组就相当于一个纯属性的对象
print(obj1.boo)
# 其实“obj1 = namedtuple("variables", ['foo', 'woo', 'boo'])(foo=1, woo=2, boo='3')”这一步相当于以下两个步骤
anonymousClass = namedtuple("variables", ['foo', 'woo', 'boo']) # 创建一个名称元组
obj1 = anonymousClass(foo=1, woo=2, boo='3') # 为名称元组赋值
(2)使用type()创建匿名类
type()是python中提供的一个函数,它可以快速创建一个类。如下:
'''
newclass=type(name, bases, dict)
三个参数是:
name - 字符串,成为新类的__name__属性的类名;
bases - 由父类组成的元组。如果不是派生类,则可以为空;
dict - 构成新类的命名空间的字典,包含属性、方法及其值。
'''
# 我们可以快速创建一个类,并创建对象
Person = type("Person", (), {
"say_hello": lambda self: print(f"Hello, my name is {self.name}.")
}) # 新类的名称为“Person”,不继承任何父类,有一个实例方法,方法中使用到一个实例属性
person = Person()
person.name = "Alice"
person.say_hello() # 输出:Hello, my name is Alice.
# 以上过程如果创建一个匿名类,则可以取消类名,并直接实例化,如下
person = type("", (), {
"say_hello": lambda self: print(f"Hello, my name is {self.name}.")
})
person.name = "Alice"
person.say_hello()
# 使用type完成(1)中的例子
obj = type('',(object,),{"foo": 1, "woo": 2, "boo": '3'})() # 继承了object
print(obj.boo)
obj = type('',(dict,),{"foo": 1, "woo": 2, "boo": '3'})() # 继承了字典
print(obj.boo)
2.7.2 内部类
python中创建类是可以进行多层嵌套的,这种定义在其他类里面类称为内部类/嵌套类。其格式如下:
## 外部类
class Outer:
## 内部类
class Inner:
def inner(self):
print("内部类inner")
## 多级内部类
class InnerInner:
def innerInner(self):
print("多级内部类")
## 另一个内部类
class _Inner:
def _inner(self):
print("内部类_inner")
def out(self):
print("外部类")
o = Outer()
# 外部访问内部类的方法可以通过“外部对象.内部类().{...}.方法名()”的方式
o.Inner().inner()
o.Inner().InnerInner().innerInner()
# 内部类之间的相互访问与类中成员之间的相互访问也是一样的道理
由于python中没有访问权限修饰符,因此外部类与内部类之间的访问权限注意事项并不像java那样复杂。