属性
• 静态属性(所有的实例共用一份=>引用)
• 普通属性(每个实例都不同的数据=>引用)
方法
• 普通(实例)方法(使用实例中的数据) => 给实例使用(一定要传递一个实例,由实例调用)
• 静态方法(无需使用实例封装的内容@staticmethod)
• 类方法(会自动加当前类的类名 @classmethod) => cls表示类本身
各种方法的区别(@staticmethod、@classmethod)
• 实例方法不能通过类名调用,但是静态方法和类方法是可以(不实例化访问)
• 实例方法:可以通过self访问实例属性
• 类方法:可以通过cls访问类属性(希望取的值不受实例影响时使用)
• 静态方法:不可以访问,通过传值的方式
#静态方法与类方法
###属性
#静态属性 --> 类属性
#普通属性 --> 实例属性
###方法
#实例方法
#静态方法
#类方法
#-------------------------------------------------------------------------------------------
class Tst():
name = "tst"
data = "this is data" # 注:静态属性
def __init__(self):
self.instance = "instance" # 注:实例属性
#普通(实例)方法
def normal_mathod(self, name):
print("normal:")
print(self.data, name) # 注:实例对象 可以访问类属性data
# def test(): # 注:直接这样写不属于实例方法
# print("test") # 注:放在类空间里面的普通函数
#类方法
@classmethod # 注:第1个参数cls 代表类本身(可以不用传)
def class_method(cls, name): # 注:cls 代表当前类
print("classmethod:")
print(type(cls),cls)
print(cls.data, name) # 注:可以使用cls.属性名访问类属性,不能访问实例属性
#静态方法
@staticmethod # 注:有几个参数 必须传几个参数
def static_method(name):
print("static_method:")
print(name, Tst.data)
cls1 = Tst() # 注:实例化对象
print(type(cls1))
#结果为 <class '__main__.Tst'>
###实例调用 类方法,实例方法,静态方法 都能通过实例去调用
cls1.class_method("classmethod") # 注:实例对象 可以访问类方法
#结果为
# classmethod:
# <class 'type'> <class '__main__.Tst'> # 注:type是所有类的源类
# this is data classmethod
cls1.normal_mathod("normalmethod") # 注:实例对象 可以访问实例方法
#结果为 normal: # this is data normalmethod
cls1.static_method("static_method") # 注:实例对象 可以访问静态方法
#结果为 static_method: # static_method this is data
###通过类名去调用实例方法的时候,需要把实例对象作为参数传递进去
###类方法和静态方法 可以通过类名去调用
Tst.normal_mathod(cls1,"normal_method")
Tst.class_method("class_method")
Tst.static_method("static_method")
###总结
#1、实例方法
# 只能通过实例对象调用,类对象调用的话,需要传递实例作为参数。
# 实例方法内部通过 self.属性名 去访问实例属性和类属性
# 使用对象调用实例方法时,第1个参数可以不用传,就代表实例本身
#2、类方法
# 可以通过实例调用,也可以通过类去调用,第1个参数代表类本身 可以不用传
# 可以使用 cls.属性名 去访问类属性
# 前面要装饰器#classmethod
#3、静态方法
# 可以通过实例对象、类名去调用,但是每个参数都必须必须传递
# 方法的内部访问属性,通过 类名.属性名 去访问类属性
# 前面要加装饰器@staticmethod
#__init__是实例方法,__new__是静态方法
以单下划线开头的(_foo)
• 类:这类成员变量叫做保护变量,意思是只有类对象和子类对象自己能访问到这些变量
•模块:如果你写了代码“from <模块/包名> import *”,那么以“”开头的模块和包都不会被导入,除非模块或包中的列表_all_
地显式包含了模块和包。
•这有点类似于惯例,为了使其他人(或你自己)使用这些代码时将会知道以“”开头的名称只供内部 使用。正如Python文档中所述:以下划线“_”为前缀的名称(如_spam)应该被视为API中非公开的 部分(不管是函数、方法还是数据成员)。此时,应该将它们看作是一种实现细节,在修改它们时无 需对外部通知
以双下划线开头的(__foo)
• 类:只有类对象自己能访问,连子类对象也不能访问到这个数据。强行访问“对象名._类名 xxx“这样的方式
• 模块:不能用“from xxx import *“导入包/模块。
• 名称(具体为一个方法名)前双下划线(““)的用法并不是一种惯例,对解释器来说它有特定 的意义。Python中的这种用法是为了避免与子类定义的名称冲突。Python文档指出,“__spam”这种形式(至少两个前导下划线,最多一个后续下划线)的任何标识符将会被“_classname__spam”这种形式原文取代,在这里“classname”是去掉前导下划线的当前类名
以双下划线开头和结尾的( foo )
• 代表Python中特殊方法专用的标识。其实,这只是一种惯例,对Python系统来说,这将确保不会 与用户自定义的名称冲突。
•例如__init__()代表类的构造函数。
• 虽然你也可以编写自己的特殊方法名,但不建议用户使用这种命名方式