Python3入门与进阶笔记(六):类

类名建议首字母大写,通常用驼峰规则命名。变量名建议小写,下划线隔开。类最基本的作用是封装。

写在类内非方法中的语句在类加载的时候会执行,且只会执行一次,例如下面的print语句,类加载时就会打印Welcome to Document。类属性在类加载的时候定义,可通过类名调用。

类方法无法访问实例变量,类方法中通过cls.变量名调用的是类变量,即使该变量名与实例变量重名,依旧是类变量,与重名的实例变量毫无关联,自然类外此时只能通过类名. 来调用,因为对象. 调用的是实例变量。

class Document():
    
    WELCOME_STR = 'Welcome! The context for this book is {}.'
    print("Welcome to Document") # 类加载的时候直接运行,只会运行一次
    
    def __init__(self, title, author, context):
        print('init function called')
        self.title = title
        self.author = author
        self.__context = context
    
    # 类函数
    @classmethod
    def create_empty_book(cls, title, author):
        return cls(title=title, author=author, context='nothing')
    
    # 成员函数
    def get_context_length(self):
        return len(self.__context)
    
    # 静态函数
    @staticmethod
    def get_welcome(context):
        return Document.WELCOME_STR.format(context)
    
    @classmethod
    def get_class_value(cls, name):
        cls.add_class_value = "我是类属性咩"
#         print(cls.title) # 不能调用普通成员属性,type object 'Document' has no attribute 'title'
        cls.author = name # 这边是类属性自己的author,不是变量关联的

print("=" * 20)    
empty_book = Document.create_empty_book('What Every Man Thinks About Apart from Sex', 
                                        'Professor Sheridan Simove')
print(empty_book.get_context_length())
print(empty_book.get_welcome('indeed nothing'))

display(empty_book)    
def display(one):
    for item in dir(one):
        if "__" in item:
            continue
        print(item, end=' ') 
    print()
Welcome to Document
====================
init function called
7
Welcome! The context for this book is indeed nothing.
WELCOME_STR author create_empty_book get_class_value get_context_length get_welcome title 
one = Document("静夜思", "李白", "床前明月光,疑是地上霜")
one.get_class_value("杜甫") # get_class_value类方法,内部对类的author做了修改,不影响实例的author
print(one.author, Document.author, empty_book.author)
Document.author = "Lucy"
print(one.author, Document.author, empty_book.author)
print("=" * 20)
display(one)
one.belong_one_only = 1 # 不建议这样加
display(one)
display(empty_book)
init function called
李白 杜甫 Professor Sheridan Simove
李白 Lucy Professor Sheridan Simove
====================
WELCOME_STR add_class_value author create_empty_book get_class_value get_context_length get_welcome title 
WELCOME_STR add_class_value author belong_one_only create_empty_book get_class_value get_context_length get_welcome title 
WELCOME_STR add_class_value author create_empty_book get_class_value get_context_length get_welcome title 

python支持多重继承,自然有可能出现一个基类的初始化函数可能被调用两次。在一般的工程中,这显然不是我们所希望的。正确的做法应该是使用 super 来召唤父类的构造函数,而且 python 使用一种叫做方法解析顺序的算法(具体实现算法叫做 C3),来保证一个类只会被初始化一次。

class A():
    def __init__(self):
        print('enter A')
        print('leave A')

class B(A):
    def __init__(self):
        print('enter B')
        A.__init__(self)
        print('leave B')

class C(A):
    def __init__(self):
        print('enter C')
        A.__init__(self)
        print('leave C')        

class D(C, B):
    def __init__(self):
        print('enter D')
        C.__init__(self) # A的初始化被调了两次,是因为C调用父类会调用一次,同理B也会再调用1次
        B.__init__(self) # 
        print('leave D')
D()

A的初始化方法被调用了两次,避免这种情况,可以使用super关键字调用父类初始化 

enter D
enter C
enter A
leave A
leave C
enter B
enter A
leave A
leave B
leave D

 python支持多重继承,自然有可能出现一个基类的初始化函数可能被调用两次。在一般的工程中,这显然不是我们所希望的。正确的做法应该是使用 super 来召唤父类的构造函数,而且 python 使用一种叫做方法解析顺序的算法(具体实现算法叫做 C3),来保证一个类只会被初始化一次。

class A():
    def __init__(self):
        print('enter A')
        print('leave A')

class B(A):
    def __init__(self):
        print('enter B')
        super().__init__()
        print('leave B')

class C(A):
    def __init__(self):
        print('enter C')
        super().__init__()
        print('leave C')        

class D(C, B):
    def __init__(self):
        print('enter D')
        super().__init__()
        print('leave D')

D()

enter D
enter C
enter B
enter A
leave A
leave B
leave C
leave D

==========================================附==========================================

类的实例化

构造函数:自动执行,可以不写return,此时返回类型是None,不能强制返回其他类型

类变量 VS 实例变量

实例方法:

      实例方法关联的是对象,实例方法通常用来操作实例变量,定义实例方法形参要多写一个self(也可以是别的,建议self),在传参数时不需要给self传值,self代表的是调用它的对象。

       在实例方法中访问实例变量,用self.变量名访问;访问类变量,用类名.变量名,或者self.__class__.变量名。

       在类的外部访问实例变量,可以用对象名.变量名;在类的外部访问类变量,可以用类名.变量名。

类方法:

       类方法关联的是类,类方法通常用来操作类变量,定义加@classmothod,形参要多写一个cls(也可以是别的,建议cls),cls代表的是调用的类,类方法不会被自动调用

       在类方法中访问类变量,用cls.变量名访问;可以用类也可以用对象调用类方法(但是不建议用对象调用类方法,毕竟逻辑不符),在类方法中不可以访问实例变量。

静态方法:

       静态方法定义加@staticmethod,不强制多传一个形参。可以用类也可以用对象调用静态方法,静态方法也可以访问类变量,和类方法没啥太多区别,在静态方法中不可以访问实例变量。不推荐用静态方法,因为静态方法不是很能体现面向对象的特点。

通过在方法名前加__将方法变为私有的,在外部不可以通过对象名/类名.__方法名访问。python在类外部可以通过对象名.变量名添加实例变量。严格来讲python并没有真正的私有变量,因为可以通过对象名._类名__变量名。

继承:

       调用父类的方法可以通过super。

https://pan.baidu.com/s/1ebpbzN6YLnUzCGxO9V-MGg

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值