Python学习从0开始——009类

一、类

3.1最简形式

class ClassName:
    <statement-1>
    .
    .
    .
    <statement-N>

3.2Class 对象

#包含三种属性引用
class MyClass:
    """A simple example class"""
    i = 12345
    def f(self):
        return 'hello world'

MyClass.i 和 MyClass.f 就是有效的属性引用,将分别返回一个整数和一个函数对象。 类属性也可以被赋值,因此可以通过赋值来更改 MyClass.i 的值。 doc 也是一个有效的属性,将返回所属类的文档字符串: “A simple example class”。

实例化操作(“调用”类对象)会创建一个空对象。 许多类喜欢创建带有特定初始状态的自定义实例。 为此类定义可能包含一个名为 init() 的特殊方法:

def __init__(self):
    self.data = []

当一个类定义了 init() 方法时,类的实例化操作会自动为新创建的类实例发起调用 init()。 因此在这个示例中,可以通过以下语句获得一个经初始化的新实例:

x = MyClass()

提供给类实例化运算符的参数将被传递给 init():

>>> class Complex:
...     def __init__(self, realpart, imagpart):
...         self.r = realpart
...         self.i = imagpart
... 
>>> x = Complex(3.0, -4.5)
>>> x.r, x.i
(3.0, -4.5)

3.3实例对象

实例对象所能理解的唯一操作是属性引用。 有两种有效的属性名称:数据属性和方法。

#类定义
>>> class MyClass:
...     """A simple example class"""
...     i = 12345
...     def f(self):
...         return 'hello world'
... 

##实例化 
>>> x = MyClass()

#属性调用
>>> x.counter = 1
>>> while x.counter < 10:
...     x.counter = x.counter * 2
... 
>>> print(x.counter)
16
>>> del x.counter
>>> print(x.counter)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'MyClass' object has no attribute 'counter'
#方法
>>> x.f()
'hello world'

另一类实例属性引用称为 方法。 方法是“从属于”对象的函数。实例对象的有效方法名称依赖于其所属的类。 根据定义,一个类中所有是函数对象的属性都是定义了其实例的相应方法。 因此在我们的示例中,x.f() 是有效的方法引用。

3.4实例变量

实例变量用于每个实例的唯一数据,而类变量用于类的所有实例共享的属性和方法:

>>> class Dog:
...     kind = 'canine'        
...     def __init__(self, name):
...         self.name = name
... 
>>> d = Dog('Fido')
>>> e = Dog('Buddy')
>>> d.kind
'canine'
>>> e.kind
'canine'
>>> d.name
'Fido'
>>> e.name
'Buddy'

设置不共享:

>>> class Dog:
...     def __init__(self, name):
...         self.name = name
...         self.tricks = []   
...     def add_trick(self, trick):
...         self.tricks.append(trick)
... 
>>> d = Dog('Fido')
>>> e = Dog('Buddy')
>>> d.add_trick('roll over')
>>> e.add_trick('play dead')
>>> d.tricks
['roll over']
>>> e.tricks
['play dead']
        

二、继承

2.1最简形式

class DerivedClassName(BaseClassName):
    <statement-1>
    .
    .
    .
    <statement-N>

方法引用将按以下方式解析:搜索相应的类属性,如有必要将按基类继承链逐步向下查找,如果产生了一个函数对象则方法引用就生效。
派生类可能会重写其基类的方法。 因为方法在调用同一对象的其他方法时没有特殊权限,所以基类方法在尝试调用调用同一基类中定义的另一方法时,可能实际上调用是该基类的派生类中定义的方法。

2.2多重继承

class DerivedClassName(Base1, Base2, Base3):
    <statement-1>
    .
    .
    .
    <statement-N>

方法解析顺序会动态改变以支持对 super() 的协同调用。所有多重继承的情况都会显示出一个或更多的菱形关联。

三、私有变量

那种仅限从一个对象内部访问的“私有”实例变量在 Python 中并不存在。
由于存在对于类私有成员的有效使用场景(例如避免名称与子类所定义的名称相冲突),因此存在对此种机制的有限支持,称为名称改写。 任何形式为 __spam 的标识符(至少带有两个前缀下划线,至多一个后缀下划线)的文本将被替换为 _classname__spam,其中 classname 为去除了前缀下划线的当前类名称。 这种改写不考虑标识符的句法位置,只要它出现在类定义内部就会进行。

class Mapping:
    def __init__(self, iterable):
        self.items_list = []
        self.__update(iterable)

    def update(self, iterable):
        for item in iterable:
            self.items_list.append(item)

    __update = update   # private copy of original update() method

class MappingSubclass(Mapping):

    def update(self, keys, values):
        # provides new signature for update()
        # but does not break __init__()
        for item in zip(keys, values):
            self.items_list.append(item)

__update 标识符会在 Mapping 类中被替换为 _Mapping__update,而在 MappingSubclass 类中被替换为 _MappingSubclass__update。

四、杂项

有时会需要使用类似于 Pascal 的“record”或 C 的“struct”这样的数据类型,将一些命名数据项捆绑在一起。 这种情况适合定义一个空类,然后添加属性:

class Employee:
    pass

john = Employee()  

john.name = 'John Doe'
john.dept = 'computer lab'
john.salary = 1000
  • 18
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值