15.面向对象

1. 类的定义

python中的类通过 class 关键字来定义,类的成员有属性方法

# 示例
class ClassName: 
    <statement-1>
    .
    .
    .
    <statement-N> 

1.1 属性

类的属性可以显式地定义在类中, 同变量一样,属性的定义必须初始化

class A:
    a = 14
    b = 12
    
print(A().a)
# 14

属性还可以隐式地通过构造方法来定义

class A:
    # 在构造方法中隐式的定义属性:
    def __init__(self):
        self.a = 13
        self.b = 12
print(A().a)
# 13

1.2 构造方法 _init(self)

Python的构造方法是名为 __init__ 的方法,第一个参数为 self, 指向当前对象。

class A:
    def __init__(self,a,b):
        self.a = a
        self.b = b
print(A(11,12).a)
# 11

1.3 类的方法

类的方法不同于函数,有一个默认参数 self

2. 继承

子类可以继承父类的属性和方法,支持多继承。

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

方法的搜索规则:

需要注意圆括号中父类的顺序,若是父类中有相同的方法名,而在子类使用时未指定,python从左至右搜索 即方法在子类中未找到时,从左到右查找父类中是否包含方法。

2.1 重写方法

  • 在子类中定义与父类相同的方法,就会在子类中重写该方法。

  • 在子类中调用父类方法,需要显示指定父类的名字(可能有多个父类)

#类定义
class people:
    #定义基本属性
    name = ''
    age = 0
    #定义私有属性,私有属性在类外部无法直接进行访问
    __weight = 0
    #定义构造方法
    def __init__(self,n,a,w):
        self.name = n
        self.age = a
        self.__weight = w
    def speak(self):
        print("%s 说: %d 岁。" %(self.name,self.age))
 
#单继承示例
class student(people):
    grade = ''
    def __init__(self,n,a,w,g):
        #调用父类的构函
        people.__init__(self,n,a,w)
        self.grade = g
    #覆写父类的方法
    def speak(self):
        print("%s 说: %d 岁了我在读 %d 年级"%(self.name,self.age,self.grade))
 
#另一个类,多重继承之前的准备
class speaker():
    topic = ''
    name = ''
    def __init__(self,n,t):
        self.name = n
        self.topic = t
    def speak(self):
        print("我叫 %s我是一个演说家我演讲的主题是 %s"%(self.name,self.topic))
 
#多重继承
class sample(speaker,student):
    a =''
    def __init__(self,n,a,w,g,t):
        student.__init__(self,n,a,w,g)
        speaker.__init__(self,n,t)
 
test = sample("Tim",25,80,4,"Python")
test.speak()   #方法名同,默认调用的是在括号中参数位置排前父类的方法

强制调用父类的方法:

s = student("Tim",12,180)

super(student,s).speak()
# Tim 说:12

3. 访问控制

3.1 私有成员

  • 类的私有属性 : __private_attrs:两个下划线开头,声明该属性为私有,不能在类的外部被使用或直接访问。在类内部的方法中使用时 self.__private_attrs

  • 类的私有方法 : __private_method:两个下划线开头,声明该方法为私有方法,只能在类的内部调用 ,不能在类的外部调用。self.__private_methods

4. 专有方法

类的专有方法:

  • __init__ : 构造函数,在生成对象时调用

  • __del__ : 析构函数,释放对象时使用

  • __repr__ : 打印,转换

  • __setitem__ : 按照索引赋值

  • __getitem__: 按照索引获取值

  • __len__ : 获得长度

  • __cmp__ : 比较运算

  • __call__ : 函数调用

  • __add__ : 加运算

  • __sub__ : 减运算

  • __mul__ : 乘运算

  • __truediv__ : 除运算

  • __mod__ : 求余运算

  • __pow__ : 乘方

class object:
    __doc__: str | None
    __dict__: dict[str, Any]
    __module__: str
    __annotations__: dict[str, Any]
    @property
    def __class__(self: Self) -> type[Self]: ...
    # Ignore errors about type mismatch between property getter and setter
    @__class__.setter
    def __class__(self, __type: type[object]) -> None: ...  # type: ignore # noqa: F811
    def __init__(self) -> None: ...
    def __new__(cls: type[Self]) -> Self: ...
    # N.B. `object.__setattr__` and `object.__delattr__` are heavily special-cased by type checkers.
    # Overriding them in subclasses has different semantics, even if the override has an identical signature.
    def __setattr__(self, __name: str, __value: Any) -> None: ...
    def __delattr__(self, __name: str) -> None: ...
    def __eq__(self, __o: object) -> bool: ...
    def __ne__(self, __o: object) -> bool: ...
    def __str__(self) -> str: ...  # noqa Y029
    def __repr__(self) -> str: ...  # noqa Y029
    def __hash__(self) -> int: ...
    def __format__(self, __format_spec: str) -> str: ...
    def __getattribute__(self, __name: str) -> Any: ...
    def __sizeof__(self) -> int: ...
    # return type of pickle methods is rather hard to express in the current type system
    # see #6661 and https://docs.python.org/3/library/pickle.html#object.__reduce__
    def __reduce__(self) -> str | tuple[Any, ...]: ...
    if sys.version_info >= (3, 8):
        def __reduce_ex__(self, __protocol: SupportsIndex) -> str | tuple[Any, ...]: ...
    else:
        def __reduce_ex__(self, __protocol: int) -> str | tuple[Any, ...]: ...

    def __dir__(self) -> Iterable[str]: ...
    def __init_subclass__(cls) -> None: ...

最后更新于