Python 快速入门笔记(7):类和对象

本系列随笔是本人的学习笔记,初学阶段难免会有理解不当之处,错误之处恳请指正。转载请注明出处:https:////www.cnblogs.com/itwhite/p/12298858.html

类的定义

示例:

class Person:
    count = 0               # 类的属性,所有对象共享
    def __init__(self, name, age):  # 构造函数
        self.name = name    # 对象的属性
        self.age = age
        Person.count += 1
    def foo(self):          # 普通成员方法(对象方法),self 相当于 C++ 中的 this 指针
        print("Hi! My name is %s, I'm %d years old." % (self.name, self.age))
    @staticmethod           # 静态方法
    def staticFoo():
        print("%d objects were created" % (Person.count))
    @classmethod            # 类的方法,使用时与静态方法一样
    def classFoo(cls):
        print("%d objects were created" % (cls.count))

jack = Person("Jack", 23)   # 创建对象
bob = Person("Bob", 25)

jack.foo()                  # 调用普通成员方法
print(jack.age)             # 直接访问对象属性
print(Person.count)         # 直接访问类的属性
print(jack.count)           # 使用对象访问类的属性

Person.staticFoo()          # 调用静态方法
Person.classFoo()           # 调用类的方法
jack.staticFoo()            # 使用对象访问静态方法
jack.classFoo()             # 使用对象访问类的方法

 

继承

示例:

class A:
    pass
class B (A):    # B 继承自 A
    pass
class C:
    pass
class D (B, C): # 多重继承,D 继承自 B 和 C
    pass

 一些类与类、对象与类之间的判断方法:

# 1. 判断某个类是否是另一个类的子类,使用内置函数 issubclass()
print(issubclass(D, A)) # True
print(issubclass(C, A)) # False

# 2. 获取某个类的基类,使用特殊属性 __bases__
print(D.__bases__)  # (<class __main__.B at 0x00000000024E68E8>, <class __main__.C at 0x00000000024E6888>)

# 3. 判断某个对象是否是某个类的实例,使用内置函数 isinstance()
c = C()
d = D()
print(isinstance(c, C)) # True
print(isinstance(c, A)) # False
print(isinstance(d, B)) # True
print(isinstance(d, C)) # True
print(isinstance(d, D)) # True

# 4. 获取某个对象所属的类,使用特殊属性 __class__
print(c.__class__)      # __main__.C
print(d.__class__)      # __main__.D

# 5. 查看对象的所有属性及值,使用特殊属性 __dict__
print(d.__dict__) # {},因为前面并未设置对象属性,因此这里为空

 

抽象类和抽象方法

示例:

from abc import ABC, abstractmethod
class A (ABC):      # 抽象类
    def __init__(self):
        self.data = 123
    @abstractmethod
    def foo(self):  # 抽象方法
        pass
    def bar(self):  # 普通方法
        pass
class D (A):
    def __init__(self):
        A.__init__(self)
    def foo(self):
        print(self.data)
d = D()
d.foo()
# a = A() # 抽象类不能实例化:TypeError: Can't instantiate abstract class A with abstract methods foo

 

旧式类与新式类

Python 中类的定义支持以下三种写法(python 2.x 和 3.x 都支持,但是意义略有差别):

class Person(object): pass  #1
class Person(): pass        #2
class Person: pass          #3

说明:

  • 在 python 3.x 中,以上三种写法效果一致,都是新式类的写法;
  • 在 python 2.x 中,#1 是新式类的写法,#2 和 #3 都是旧式类的写法,一般使用 #1 的写法。

 

super():子类中调用父类方法 

有时候需要在子类中调用父类方法来初始化,例如:

class A:
    def __init__(self):
        print("A::__init__() is called")
        self.foo = 123
class B (A):
    def __init__(self):
        A.__init__(self)    # 直接通过类名调用父类中定义的方法
b = B()     # A::__init__() is called

python 中定义了 super() 方法用来调用父类方法并推荐使用,但是个人觉得并不是太好,一方面 python 2.x 和 python 3.x 中的使用方式不一样,另一方面当有多重继承时无法控制调用哪些父类的方法,例如:

# python 2.x 版本
class A (object):   # 基类必须是新式类
    def __init__(self):
        print("A::__init__() is called")
        self.foo = 123
class B (object):
    def __init__(self):
        print("B::__init__() is called")
        self.bar = 456
class C (A, B):
    def __init__(self):
        super(C, self).__init__()  # 或者 super(self.__class__, self),super() 中需要参数
c = C()     # A::__init__() is called

# python 3.x 版本
class A:            # 默认就是新式类了
    def __init__(self):
        print("A::__init__() is called")
        self.foo = 123
class B:
    def __init__(self):
        print("B::__init__() is called")
        self.bar = 456
class C:
    def __init__(self):
        super().__init__()         # super() 中不需要参数
c = C()     # A::__init__() is called

上面的示例中,通过 super() 只能调用父类 A 的构造函数,而父类 B 的构造函数没能调用,bar 属性无法得到初始化,这也是个人不喜欢 super() 的原因,不知道有没有别的好的解决方法。

 

类的嵌套

示例:

class A:
    class B:        # 类嵌套
        def foo(self):
            print("B::foo() is called")
    def foo(self):
        print("A::foo() is called")
        class C:    # 方法中定义类
            def foo(self):
                print("C::foo() is called")
        c = C()
        return c
a = A()
b = A.B()
c = a.foo() # A::foo() is called
b.foo()     # B::foo() is called
c.foo()     # C::foo() is called

 

对象方法与普通函数

示例:

class A:
    def __init__(self, data):
        self.data = data
    def foo(self):  # 对象方法
        print("A::foo() is called, data is %d" % (self.data))
def bar(obj):       # 普通函数
    print("bar() is called, data is %d" % (obj.data))

a1 = A(123)
a1.foo()     # A::foo() is called, data is 123
a1.foo = bar # 这里能够替换 对象的方法 哦
a1.foo(a1)   # bar() is called, data is 123

a2 = A(456)
qux = a2.foo # 调用时会自动传入 a2 对象哦
qux()        # A::foo() is called, data is 456

 

完。

posted @ 2020-02-12 15:17  itwhite  阅读(298)  评论(0编辑  收藏  举报