类名建议首字母大写,通常用驼峰规则命名。变量名建议小写,下划线隔开。类最基本的作用是封装。
写在类内非方法中的语句在类加载的时候会执行,且只会执行一次,例如下面的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