@SuHongjun
2020-11-24T08:52:01.000000Z
字数 3260
阅读 308
Python
2020春季学期
class 类名(): #class是类定义的关键字
多个(≥0)类属性...
多个(≥0)方法...
'''
class 类名: #旧的书写方式
多个(≥0)类属性...
多个(≥0)方法...
'''
类中的属性和方法统称为成员
类是一个模板,而对象是类的实例。类好比是设计图,而对象是按照设计图生产出来的产品。
class A( ):
pass
x = A( ) #类的实例化, x是class A的一个对象
y = A #不是类的实例化,只是给 class A取了一个别名
class people( ):
'''这里是类的说明文档'''
pass
class C1():
pass
class C2():
a1 = "John" #属性 ,类属性 class attribute
a2 = 27 #属性 ,类属性 class attribute
class C3():
def sayHi(self): #实例方法 instance method
print("Hello")
>>> o=C3() #类的实例化:创建对象
>>> o.sayHi() #实例方法的调用
Hello
>>> o2 = C3 #不是实例化,而是给类起了一个别名
>>> o2.sayHi() #出错:TypeError: sayHi() missing 1 required positional argument: 'self'
python实例化对象时要在类名后加上小括号,如果不带括号则是给类对象起了一个别名,不会创建实例。
在类体中,根据变量定义的位置不同,以及定义的方式不同,类中的变量分为 3 种:
类体中,所有函数之外: 此范围定义的变量,称为类属性或类变量;
类体中,函数内部: 以“self.变量名”的方式定义的变量,称为实例属性或实例变量;
类体中,函数内部: 以“变量名=变量值”的方式定义的变量,称为局部变量。
class c5():
a1 = "Jack" #class attribute,类属性
a2 = 21 #class attribute,类属性
def sayHi(self,name='小王'): #instance method,实例方法
self.xm = name # xm: instance attribute, 实例属性
x = 3 # x: 局部变量
print("Hi",self.xm)
类体中的函数叫做方法。
方法分为:
实例方法:通常情况下,在类中定义的方法默认都是实例方法,实例方法至少要有一个参数,按一般惯例第一个参数是self。实例方法通常用类对象直接调用。
类方法:需要使用@classmethod修饰符进行修饰 (以后介绍)
静态方法:需要使用@staticmethod修饰。 (以后介绍)
静态方法,其实就是我们学过的函数,和函数唯一的区别是,静态方法定义在类这个空间(类命名空间)中,而函数则定义在程序所在的空间(全局命名空间)中。
class Person4( ): #定义类Person4
def say_hi(self, n): #定义实例方法say_hi
self.name = n #创建实例属性,把参数n赋值给实例属性self.name
print('您好, 我叫', self.name)
p4 = Person4() #创建对象
#print(p4.name) #出错,因为还没有调用say_hi(), 而name是在调用say_hi()的时候才创建出来的
p4.say_hi('Alice') #调用对象的实例方法
print(p4.name) #正确
class C:
@staticmethod #静态方法
def f(arg1, arg2, ...): ...
#It can be called either on the class (such as C.f()) or on an instance (such as C().f()).
class C:
@classmethod #类方法
def f(cls, arg1, arg2, ...): ...
#It can be called either on the class (such as C.f()) or on an instance (such as C().f()).
class Foo( ):
classname = "Foo"
def __init__(self, n):
self.name = n #创建实例属性
def f1(self): #实例方法
print(self.classname + ',实例方法') #实例方法中引用类属性
print(self.name + ',实例方法') #引用实例属性
@staticmethod
def f2(): #静态方法
print("static静态方法")
@classmethod
def f3(cls): #类方法
print(cls.classname + ',类方法') #类方法中引用类属性,不能用self.classname
#测试代码
print("用类名调用静态方法、类方法:")
Foo.f2() #用类名调用 静态方法
Foo.f3() #用类名调用 类方法
#Foo.f1() #这样调用将会出错,因为没有了隐式的self参数传递
f = Foo("李晓东")
f.f1() #实例方法调用
print("用对象调用静态方法、类方法:")
f.f2()
f.f3()
输出:
用类名调用静态方法、类方法:
static静态方法
Foo,类方法
Foo,实例方法
李晓东,实例方法
用对象调用静态方法、类方法:
static静态方法
Foo,类方法
Python 也支持使用类名调用实例方法,但此方式需要手动给 self 参数传值。例如:
#类名调用实例方法,需手动给 self 参数传值
clang = CLanguage()
CLanguage.say(clang) #既然叫实例方法,当然是要结合某个实例(对象)才行
在实际编程中,很少用到类方法和静态方法,因为我们完全可以使用函数代替它们实现想要的功能。在一些特殊的设计模式(例如工厂模式)中会用到类方法和静态方法。
一般而言,类属性作用于该类的所有对象,但前提是该对象没有同名的实例属性,如果有同名的实例属性,则该对象内会屏蔽掉同名的类属性。
class c( ):
a1 = 5 #类属性
obj1 = c( )
obj2 = c( )
>>> obj1.a1
5
>>> obj2.a1
5
>>> c.a1 = 8 #这是正确的修改类属性的方式,类名c不带()
>>> obj1.a1
8
>>> obj2.a1
8
>>> c().a1 = 10 #这里试图修改类属性,但其实是创建了一个同名的实例属性,所以没有修改类属性
>>> obj1.a1
8
>>> obj2.a1
8
>>> obj1.a1 = 20 #这里并不是修改类属性,而是在obj1对象创建了一个和类属性同名的实例属性
>>> obj1.a1
20 #和类属性同名的实例属性屏蔽了类属性
>>> obj2.a1
8 #类属性的值没有变化
class Person3:
count = 0 #定义属性count,表示计数
name = "Jack" #定义属性name1,表示名称
#测试代码
Person3.count += 1 #通过类名访问,将计数加1
print(Person3.count) #类名访问,读取并显示类属性
print(Person3.name) #类名访问,读取并显示类属性
p1 = Person3() #创建实例对象1
p2 = Person3() #创建实例对象2
print((p1.name, p2.name)) #通过实例对象访问,读取成员变量的值
Person3.name = "Tom" #通过类名访问,设置类属性值
print((p1.name, p2.name)) #读取成员变量的值
p1.name = "Alice" #p1.name实际上并没有引用类属性name,而是给p1对象创建了一个新的实例属性name,
#而新的实例属性name屏蔽了同名的类属性name
print((p1.name, p2.name))