语法
实例方法:
第一个参数必须要默认传实例对象,一般用self,代表实例本身
只能被实例对象调用
静态方法:
用@staticmethod装饰,参数没有要求
可以被类或类的对象(即实例)调用
【跟类有关,但实现时并不需要引用类或者实例,如设置环境变量、修改另一个类的变量等】
类方法:
用@classmethod装饰,第一个参数必须默认传类,一般用cls,代表类本身
可以被类或类对象(即实例)调用
【当一个方法中只涉及到静态属性的时候可以使用类方法(类方法用来修改类属性)】
class Foo(object):
"""类三种方法语法形式"""
def instance_method(self):#self表示实例本身
print("是类{}的实例方法,只能被实例对象调用".format(Foo))
@staticmethod
def static_method():
print("是静态方法")
@classmethod
def class_method(cls):#cls表示类本身
print("是类方法")
print('--------实例调用--------')
foo = Foo()
foo.instance_method()
foo.static_method()
foo.class_method()
print('--------类调用--------')
# Foo.instance_method() #报错
Foo.static_method()
Foo.class_method()
运行结果如下
--------实例调用--------
是类<class '__main__.Foo'>的实例方法,只能被实例对象调用
是静态方法
是类方法
--------类调用--------
是静态方法
是类方法
使用区别和说明场景
类方法用于模拟java中定义多个构造函数的情况
python类中只能有一个初始方法,不能按照不同的类型初始化类
class Book(object):
def __init__(self, title):#构造函数
self.title = title
@classmethod
def class_method_create(cls, title):
book = cls(title=title)
return book
@staticmethod
def static_method_create(title):
book = Book(title)#静态方法需要用类名调用
return book
book1 = Book("use instance_method_create book instance")
book2 = Book.class_method_create("use class_method_create book instance")
book3 = Book.static_method_create("use static_method_create book instance")
print(book1.title)
print(book2.title)
print(book3.title)
运行结果如下
use instance_method_create book instance
use class_method_create book instance
use static_method_create book instance
静态方法调用静态方法&类方法调用静态方法
class Foo(object):
X = 1
Y = 2
@staticmethod
def averag(*mixes):
return sum(mixes) / len(mixes)
@staticmethod
def static_method(): # 在静态方法中调用静态方法
print
"在静态方法中调用静态方法"
return Foo.averag(Foo.X, Foo.Y)
@classmethod
def class_method(cls): # 在类方法中使用静态方法
print
"在类方法中使用静态方法"
return cls.averag(cls.X, cls.Y) #用cls代替类调用,代码更简洁
foo = Foo()
print("-------静态方法调用静态方法--------")
print(foo.static_method())
print("-------类方法调用静态方法--------")
print(foo.class_method())
运行结果如下
-------静态方法调用静态方法--------
1.5
-------类方法调用静态方法--------
1.5
继承的区别
子类覆盖父类的静态方法averag:
(1)子类调用static_method方法,调用的还是父类的方法和属性
(2)子类调用class_method方法,调用的是子类的方法和属性
子类不覆盖父类的averag:
(1)子类调用static_method方法,调用的是父类的方法和属性
(2)子类调用class_method方法,调用的是父类的方法和子类的属性
'''
子类覆盖父类的静态方法averag:
(1)子类调用static_method方法,调用的还是父类的方法和属性
(2)子类调用class_method方法,调用的是子类的方法和属性
'''
class Foo(object):
X = 1
Y = 14
@staticmethod
def averag(*mixes): # "父类中的静态方法"
print("Foo的averag方法 ", mixes)
return sum(mixes) / len(mixes)
@staticmethod
def static_method(): # "父类中的静态方法"
print("父类中的静态方法")
return Foo.averag(Foo.X, Foo.Y)
@classmethod
def class_method(cls): # 父类中的类方法
print("父类中的类方法")
return cls.averag(cls.X, cls.Y)
class Son(Foo):
X = 3
Y = 5
@staticmethod
def averag(*mixes): # "子类中重载了父类的静态方法"
print("子类中重载了父类的静态方法")
print("son的averag方法 ", mixes)
return sum(mixes) / 3
p = Son()
print("------result of p.averag(1,5)------")
print(p.averag(1, 5))
print("------result of p.static_method()--------")
print(p.static_method())
print("------result of p.class_method()------")
print(p.class_method())
运行结果如下
------result of p.averag(1,5)------
子类中重载了父类的静态方法
son的averag方法 (1, 5)
2.0
------result of p.static_method()--------
父类中的静态方法
Foo的averag方法 (1, 14)
7.5
------result of p.class_method()------
父类中的类方法
子类中重载了父类的静态方法
son的averag方法 (3, 5)
2.6666666666666665
'''
子类不覆盖父类的averag:
(1)子类调用static_method方法,调用的是父类的方法和属性
(2)子类调用class_method方法,调用的是父类的方法和子类的属性
'''
class Foo(object):
X = 1
Y = 14
def averag(self,*mixes):
self.mixes=mixes
print("Foo的averag方法 ", self.mixes)
return sum(self.mixes) / len(self.mixes)
@staticmethod
def static_method(): # "父类中的静态方法"
print("父类中的静态方法")
return Foo().averag(Foo.X, Foo.Y) #调用实例方法用实例调用。Foo是类,Foo()是实例
@classmethod
def class_method(cls): # 父类中的类方法
print("父类中的类方法")
return cls().averag(cls.X, cls.Y)#调用实例方法用实例调用。cls是类,cls()是实例
class Son(Foo):
X = 3
Y = 5
p = Son()
print("------result of p.averag(1,5)------")
print(p.averag(1, 5))
print("------result of p.static_method()--------")
print(p.static_method())
print("------result of p.class_method()------")
print(p.class_method())
运行结果:
------result of p.averag(1,5)------
Foo的averag方法 (1, 5)
3.0
------result of p.static_method()--------
父类中的静态方法
Foo的averag方法 (1, 14)
7.5
------result of p.class_method()------
父类中的类方法
Foo的averag方法 (3, 5)
4.0
属性方法(property)
可以称作属性方法,可以修改参数,但是不能随意修改
方法一:绑定属性,属性直接暴露,可以随意修改属性值,未做校验
class Student(object):
pass
s=Student()
s.score='abc'
print(s.score)
运行结果:
abc
方法二:通过set_score()检查参数,通过get_score()获取参数;此方法调用较复杂
class Student(object):
def get_score(self):
return self._score
def set_score(self,value):
if not isinstance(value,int):
raise ValueError('score must be an integer!')
if value<0 or value >100:
raise ValueError('score must between 0~100!')
self._score=value
s=Student()
s.set_score(100)
print(s.get_score())
s.set_score('abc')
print(s.get_score())
运行结果:
Traceback (most recent call last):
File "E:/learning/proexe/main.py", line 14, in <module>
s.set_score('abc')
File "E:/learning/proexe/main.py", line 6, in set_score
raise ValueError('score must be an integer!')
ValueError: score must be an integer!
100
方法三:python内置的@property装饰器可以实现上述功能,且调用方法简单
方法二与方法三中,get/set函数名一样,分别多了装饰器@property和@score.setter
@property 加了这个装饰器的func相当于getfunc()
@score.setter加了这个装饰器的func相当于setfunc
class Student(object):
@property
def score(self):
return self._score
@score.setter
def score(self,value):
if not isinstance(value,int):
raise ValueError('score must be an integer!')
if value<0 or value >100:
raise ValueError('score must between 0~100!')
self._score=value
s=Student()
s.score=99
print(s.score)
s.score=101
print(s.score)
运行结果:
99
Traceback (most recent call last):
File "E:/learning/proexe/main.py", line 16, in <module>
s.score=101
File "E:/learning/proexe/main.py", line 10, in score
raise ValueError('score must between 0~100!')
ValueError: score must between 0~100!
实现property属性的两种方式
补充一:python内置的@property装饰器用法补充
@property对应读取
@方法名.setter修改
@方法名.deleter删除属性
class Student:
def __init__(self):
self._score = 60
@property
def score(self): # 读取
return self._score
# 方法名.setter
@score.setter # 设置,仅可接收除self外的一个参数
def score(self, value):
if not isinstance(value, int):
raise ValueError('score must be an integer!')
if value < 0 or value > 100:
raise ValueError('score must between 0~100!')
self._score = value
# 方法名.deleter
@score.deleter # 删除
def score(self):
del self._score
# ############### 调用 ###############
obj = Student() # 实例化对象
obj.score # 直接获取 score属性值
obj.score = 90 # 修改score的值
print(obj.score)
del obj.score # 删除score属性的值
补充二:类属性
当使用类属性的方式创建property属性时,property()方法有四个参数
第一个参数是方法名,调用 对象.属性 时自动触发执行方法
第二个参数是方法名,调用 对象.属性 = XXX 时自动触发执行方法
第三个参数是方法名,调用 del 对象.属性 时自动触发执行方法
第四个参数是字符串,调用 对象.属性.doc ,此参数是该属性的描述信息
class Student(object):
def __init__(self):
self._score=60
def get_score(self):
return self._score
def set_socre(self, value):
if not isinstance(value, int):
raise ValueError('score must be an integer!')
if value < 0 or value > 100:
raise ValueError('score must between 0~100!')
self._score = value
def del_score(self):
del self._score
# 获取 设置 删除 描述文档
SCORE = property(get_score, set_socre, del_score, '属性描述...')
# 使用此方式设置
obj = Student()
obj.SCORE # 获取score
obj.SCORE= 99 # 修改score
print(obj.SCORE)
del obj.SCORE # 删除score