属性分为实例属性与类属性
方法分为普通方法,类方法,静态方法
一:属性:
尽量把需要用户传入的属性作为实例属性,而把同类都一样的属性作为类属性。实例属性在每创造一个类是都会初始化一遍,不同的实例的实例属性可能不同,不同实例的类属性都相同。从而减少内存。
1:实例属性:
最好在__init__(self,...)中初始化
内部调用时都需要加上self.
外部调用时用instancename.propertyname
2:类属性:
在__init__()外初始化
在内部用classname.类属性名调用
外部既可以用classname.类属性名又可以用instancename.类属性名来调用
3:私有属性:
1):单下划线_开头:只是告诉别人这是私有属性,外部依然可以访问更改
2):双下划线__开头:外部不可通过instancename.propertyname来访问或者更改
实际将其转化为了_classname__propertyname
二:方法
1:普通类方法:
def fun_name(self,...):
pass
外部用实例调用
2:静态方法:@staticmethod
不能访问实例属性!!! 参数不能传入self!!!
与类相关但是不依赖类与实例的方法!!
3:类方法:@classmethod
不能访问实例属性!!! 参数必须传入cls!!!
必须传入cls参数(即代表了此类对象-----区别------self代表实例对象),并且用此来定义类属性:cls.类属性名
*静态方法与类方法都可以通过类或者实例来调用。其两个特点都是不能够调用实例属性。
1.先看下静态方法和类方法
1 """ 2 静态方法和类方法 3 已知,类的方法第一个参数必须是self,并且如果要调用类的方法,必须将通过类的实例,即方法绑定实例后才能由实例调用。 4 如果不绑定,一般在继承关系的类之间,可以用super函数等方法调用。 5 6 这里再介绍一种方法,这种方法的调用方式跟上述的都不同,这就是:静态方法和类方法。看代码: 7 """ 8 class StaticMethod: 9 @staticmethod #静态方法 10 def foo(): 11 print "This is static method foo()" 12 13 class ClassMethod: 14 @classmethod #类方法 15 def bar(cls): 16 print "this is class method bar()" 17 print "bar() is part of class:",cls.__name__ 18 19 if __name__ == "__main__": 20 static_foo = StaticMethod() #实例化 21 static_foo.foo() #实例调用静态方法 22 StaticMethod.foo() #通过类来调用静态方法 23 print "*********" 24 class_bar = ClassMethod() #实例化 25 class_bar.bar() #实例调用类方法 26 ClassMethod.bar() #通过类直接调用类方法
2.静态方法和类方法调用实例属性(测试代码)
1 class A: 2 member = "this is a test." 3 def __init__(self): 4 pass 5 6 @classmethod 7 def Print1(cls): 8 print "print 1: ", cls.member 9 10 def Print2(self): 11 print "print 2: ", self.member 12 13 14 @classmethod 15 def Print3(paraTest): 16 print "print 3: ", paraTest.member 17 @staticmethod 18 def print4(): 19 print "hello"
报错信息:
AttributeError: type object 'A1' has no attribute 'scord'
类属性是属于一个类的变量,就像是C++中类的静态成员变量,你只需将该属性定义在所有方法的作用域外,即为类属性,但一般是紧跟在类名后面,类属性为所有实例所共有,你可以通过 类名.属性 来调用类属性
- >>> class A:
- count = 0; #这就是类属性
- def __init__(self):
- A.count += 1 #每次调用该方法 count 自增 1
- def output(self):
- print(self.count)
- >>> a1 = A()
- >>> a1.output()
- 1
- >>> A.count = 0
- >>> A.count
- 0
- >>> a1.output()
- 0
实例属性是属于实例自己的属性,你可以在任何方法中添加新的实例属性,甚至在类外添加,Python会在实例属性初次使用时,创建该属性并赋值
- >>> class A:
- def __init__(self):
- self.num = 1 #添加实例属性num
- def again(self,name):
- self.name = name #添加实例属性name
- >>> a1 = A()
- >>> a1.num
- 1
- >>> a1.name #这时实例 a1 中还没有实例属性 name
- Traceback (most recent call last):
- File "<pyshell#38>", line 1, in <module>
- a1.name #这时实例 a1 中还没有实例属性 name
- AttributeError: 'A' object has no attribute 'name'
- >>> a1.again('Jane')
- >>> a1.name #现在有了...
- 'Jane'
- >>> a1.call = '123456' #添加a1的实例属性 call
- >>> a1.call
- '123456'
继续看下面的例子:
- >>> class A:
- count = 0
- def __init__(self):
- A.count += 1
- def output(self):
- print(self.count)
- >>> a1 = A()
- >>> a2 = A()
- >>> a3 = A()
- >>> A.count # A的类属性count这时为3
- 3
- >>> A.count = 2 #更改A的类属性为2
- >>> a1.count,a2.count, a3.count, A.count #A的所有实例的count也同样改变
- (2, 2, 2, 2)
- >>> a1.count = 5 #通过A的一个实例a1更改count
- >>> a1.count, a2.count, a3.count, A.count #只有a1的count发生改变
- (5, 2, 2, 2)
- >>> A.count = 4 #再次更改A的类属性为4
- >>> a1.count, a2.count, a3.count, A.count #这时a1的count还是保持为5
- (5, 4, 4, 4)
通过上面的例子我们可以看到,类属性为所有实例和类所共有,通过 类名.类属性 可以更改类属性,并且所有实例的类属性也随之改变,但通过
实例名.类属性 来改变类属性,该实例的该类属性会变为实例属性,而不影响其他实例的类属性,以后通过 类名.类属性
来更改类属性,也不会影响到该实例的这个属性了,因为它变为实例属性啦。