类中的变量
类变量(类属性)
类定义内部定义的变量
可以由类名直接调用,也可以有对象来调用
class Student(object):
count = 0
def __init__(self, name, score):
self.name = name
self.score = score
Student.count += 1
self.num = Student.count
成员变量(实例属性)
类定义内部__init__函数内以self开头定义的变量(可以不在__init__函数中声明,但最好在__init__中初始化)
成员变量,可以由类的对象来调用
类中的函数
类方法
定义:使用装饰器@classmethod。第一个参数必须是当前类对象,该参数名一般约定为“cls”,通过它来传递类的属性和方法(不能传实例的属性和方法);
调用:类和实例对象都可以调用。
类内部定义的以@classmethod装饰的函数是类方法
传递给类方法的第一个参数是一个类对象而不是一个实例
对于类方法,python自动把类(而不是实例)传入类方法第一个(最左侧)参数中,不管它是通过一个类或一个实例调用
类方法也算一种实用的技巧,简单描述之:“类方法让类模板具有记忆力”。
类模板就是我们所定义的类。在普通情况下,不使用类方法对类进行实例化,类本身是不具有记忆性的。只是当一个静态模板被套用多次而已。
示例:
class A(object):
count = 0
def fun(self):
b = "world"
return b
@classmethod
def create(cls):
print("create--------")
if __name__ == '__main__':
# 不需要实例化,类名称直接调用类方法
A.create()
# 实例化也能调用类方法
a = A()
a.create()
静态方法
定义:使用装饰器@staticmethod。参数随意,没有“self”和“cls”参数,但是方法体中不能使用类或实例的任何属性和方法;
调用:类和实例对象都可以调用。
类内部定义的以@staticmethod装饰的函数
嵌套在一个类中的没有self参数的简单函数,并且旨在操作类属性而不是实例属性。
静态方法的出现就是为了在类里面可以写一个函数,当普通的函数去调用。
静态方法不需要实例化可以直接调用,实例化后也能调用,可以理解成函数。
示例:
class A(object):
count = 0
def fun(self):
b = "world"
return b
@staticmethod
def start():
print("start-----")
if __name__ == '__main__':
# 不用实例化也能调用
A.start()
# 实例化也能调用
a = A()
a.start()
实例方法
定义:第一个参数必须是实例对象,该参数名一般约定为“self”,通过它来传递实例的属性和方法(也可以传类的属性和方法);
调用:只能由实例对象调用。
类内部定义的没有装饰器且第一个参数为self的函数
实例方法是常规的(并且是默认的)情况。
一定要用实例对象调用实例方法。
通过实例调用时,Python会把实例自动传给第一个(最左侧)参数。
示例:
class A(object):
count = 0
def fun(self):
b = "world"
return b
if __name__ == '__main__':
## 实例方法 ##
# A类不能直接调用fun
# print(A.fun())
a = A()
print(a.fun())
普通函数
类内部定义的既没有装饰器,也没有参数self的函数
python3.0中允许类中的简单函数(非实例函数)在通过一个类调用的时候充当静态方法的角色
示例:
class A(object):
count = 0
def common_fun():
a = "hello"
return a
def fun(self):
b = "world"
return b
if __name__ == '__main__':
## 普通函数 ##
# 充当静态方法
print(A.common_fun())
类方法与静态方法的区别
1、类方法用在模拟java定义多个构造函数的情况。 由于Python类中只能有一个初始化方法,不能按照不同的情况初始化类。特别说明,静态方法也可以实现上面功能,但静态方法每次都要写上类的名字,不方便。
2、类中静态方法方法调用静态方法的情况。
静态方法调用另一个静态方法,如果改用类方法调用静态方法,可以让cls代替类,让代码看起来精简一些。也防止类名修改了,不用在类定义中修改原来的类名。
3、继承类中的区别:
当子类继承父类的方法时,子类覆盖了父类的静态方法的情况下;
子类的实例继承了父类的static_method静态方法,调用该方法,还是调用的父类的方法和类属性。
子类的实例继承了父类的class_method类方法,调用该方法,调用的是子类的方法和子类的类属性。
类接口化技术
点号运算
点号运算:赋值和引用
属性点号运算其实内部就是字典的索引运算,而属性继承其实就是搜索链接的字典而已
模块,类和实例都是如此
实例和类对象就是python中带有链接的字典而已
属性实际上是python中的字典键
dir(object)类似于object.__dict__.keys()调用,不过dir会排序其列表并引入一些系统属性,在python3.0中dir包含了从所有类的隐含超类object类继承的名称。
总结:模块,类,对象都是命名空间,命名空间都是以字典的形式实现的。
global和nonlocal可以修改赋值的命名空间绑定规则。
python中可调用判断
1、使用内置的callable函数
callable(func)
用于检查对象是否可调用,返回True也可能调用失败,但是返回False一定不可调用
2、判断对象类型是否是FunctionType
type(func) is FunctionType
# 或者
isinstance(func, FunctionType)
3、判断对象是否实现__ call__ 方法
hasattr(func, '__call__')
类与对象的比喻
铸模:类
铸件:实例
类属性与类方法都是针对类的
实例属性和实例方法都是针对实例的
静态方法不能使用类或实例的任何属性和方法