1. 定义实例方法
实例方法和普通方法的区别:
实例方法必须定义在类中
实例方法的第一个参数永远是那个具体的对象, 而且不需要调用者手动传入, python 会自动传入那个对象. 而且这个形参一般命名为
self
实例方法调用方式:
对象.实例方法(实参)
class Student:
def __init__(self, name):
self.name = name
# 定义一个实例方法:一个参数表示具体的对象, python 会默认传入
def speak(self):
print("我的名字是:" + self.name) # 在实例方法中访问实例变量
s = Student("志玲")
s.speak()
self
的理解
学过其他语言的人都知道, python 的 self 其实就是在其他语言的this
.
那么self
到底指代哪个对象?
通过哪个对象调用的这个实例方法, 那么这个实例方法中的self
就指代谁
而且 python 的self
一朝绑定, 终身不便. (不像 javascript 中的那个 this
小婊砸随着调用方式的不同而而更改绑定对象, 让你眼花缭乱到怀疑人生)
class Student:
def __init__(self, name):
self.name = name
# 定义一个实例方法:一个参数表示具体的对象, python 会默认传入
def speak(self):
print("我的名字是:" + self.name) # 在实例方法中访问实例变量
s = Student("志玲")
# s.speak 的 this 永远指定的是 s 对象
foo = s.speak # 重新定义一个变量, 指向了对象 s 的 speak 方法.
foo() # 则 self 仍然绑定的是 s 对象
class Student:
def __init__(self, name):
self.name = name
def speak(self):
print("我的名字是:" + self.name) # 在实例方法中访问实例变量
s1 = Student("志玲")
s2 = Student("凤姐")
s2.speak = s1.speak
s2.speak()
说明:
把s1.speak
表示的那个方法赋值给s2.speak
, 虽然你调用的时候使用的是s2.speak()
, 但是他指向的那个方法的self
已经永远的绑定到了s1
2. 定义类方法
类方法和实例方法的区别:
一个方法想成为类方法, 需要在方法的上面要添加一个内置装饰器:
@classmethod
实例方法的第一个参数是具体的对象, 而类方法的第一个参数是类对象.(python 中一切皆对象, 那么类本身也是个对象, 我们一般称之为类对象). 类对象也是 python 自动传递. (类对象一般起名为
cls
)调用实例方法使用
对象.实例方法(实参)
, 而调用类方法使用类名.类方法(实参)
类方法中可以访问类变量, 但是不能访问实例变量, 因为没有
self
啊.
class Student:
country = "china"
@classmethod
def say(cls):
print("我们的国家是:" + cls.country)
Student.say()
什么时候使用类方法
如果一个方法不需要操作实例变量, 则这个方法建议定义成类方法!
注意:
有一点注意, 类方法也可以通过实例对象来调用, 但是不管怎么调用, 类方法的第一个参数总是类对象!
class Student:
country = "china"
@classmethod
def say(cls):
print("我们的国家是:" + cls.country)
Student.say()
s = Student()
s.say()
3. 定义静态方法
静态方法其实是一种普通的函数, 他仅仅是处于类的命名空间中.(把当前类作为了他的命名空间, 其他情况与普通函数没有任何区别).
定义静态方法只需要在函数的上面添加一个装饰器:
@staticmethod
调动静态方法:
类名.静态方法(实参)
. 只需要把类名作为他的前缀来执行, 与普通函数相比, 没有其他任何多余的操作!
class Student:
@staticmethod # 定义静态方法
def create_student():
print("我是个静态方法")
Student.create_student()
静态方法的应用场景
因为 python 的类中只有一个__init__()
方法, 意味着创建对象的方式只能有一种.
我们可以使用静态方法给外界提供其他的创建对象的方式.
import time
class Date:
"""
创建一个表示日期的类
"""
def __init__(self, year, month, day):
self.year = year
self.month = month
self.day = day
@staticmethod
def now():
"""
创建表示当前日期的对象
:return:
"""
t = time.localtime()
return Date(t.tm_year, t.tm_mon, t.tm_mday)
@staticmethod
def tomorrow():
"""
创建表示明日日期的对象
:return:
"""
t = time.localtime(time.time() + 60 * 60 * 24)
return Date(t.tm_year, t.tm_mon, t.tm_mday)
now = Date.now()
print("现在是: %d年%d月%d日" % (now.year, now.month, now.day))
now = Date.tomorrow()
print("明天是: %d年%d月%d日" % (now.year, now.month, now.day))