python学习过程中经常遇到cls、self有什么区别,类和函数带不带括号什么区别,创建类带不带括号有什么区别,这里打算汇总一下
1、创建类时加不加括号的区别:
class A:
pass
class A():
pass
class A(object):
pass
在python2中他们是有一些差别的,不加括号的,或者加括号未继承其他类的是经典类(旧式类) ,加括号继承其他类或者Object的是新式类,对 object 的继承需要显式地写为 FrenchDeck(object)。
python3中都是新式类,这个继承关系是默认的,所以他们无差别
2、类实例化的时候加不加括号的区别:
class A():
def __init__(self):
print("init调用")
A
》》
什么都不会输出
A()
》》
init调用
- 不带括号A
- 本质上是给类对象起了一个别名也可以说是赋值,类似C语言中的typedef关键字,而并不会创建一个实例。
- 不加括号不会调用__init__函数
- 一般要使用某个类的方法,需要先实例化一个对象再调用方法。如果类上有@staticmethod或@classmethod,就可以不需要实例化,直接类名.方法名()来调用。
- 加括号A()
- 是对类的实例化
- 会调用__init__函数
class A():
@classmethod
def printcls(cls):
print("这里是A(cls):", cls)
def printself(self):
print("这里是A(self):", self)
a=A()
b=A()
print("A:",A)
print("id(A):",id(A))
print("================")
print("a=A():",a)
print("id(a=A())",id(a))
print("b=A():",b)
print("id(b=A())",id(b))
print("================")
print("A().printcls:",a.printcls)
print("id(A().printcls):",id(a.printcls))
print("================")
print("A.printcls():",A.printcls)
print("id(A.printcls()):",id(A.printcls))
print("================")
print("A().printcls:",a.printcls())
print("id(A().printcls):",id(a.printcls()))
print("================")
print("A().printcls():",A.printcls())
print("id(A().printcls()):",id(A.printcls()))
print("================")
print("A().printself:",a.printself)
print("id(A().printself):",id(a.printself))
print("================")
print("A().printself():",a.printself())
print("A().printself():",id(a.printself()))
打印的结果是:
A: <class ‘main.A’>
id(A): 2916515497632
================
a=A(): <main.A object at 0x000002A70FC87FD0>
id(a=A()) 2916547592144
b=A(): <main.A object at 0x000002A70FC879A0>
id(b=A()) 2916547590560
================
A().printcls: <bound method A.printcls of <class ‘main.A’>>
id(A().printcls): 2916546048064
================
A.printcls(): <bound method A.printcls of <class ‘main.A’>>
id(A.printcls()): 2916546048064
================
这里是A(cls): <class ‘main.A’>
A().printcls: None
这里是A(cls): <class ‘main.A’>
id(A().printcls): 140726019065984
================
这里是A(cls): <class ‘main.A’>
A().printcls(): None
这里是A(cls): <class ‘main.A’>
id(A().printcls()): 140726019065984
================
A().printself: <bound method A.printself of <main.A object at 0x000002A70FC87FD0>>
id(A().printself): 2916546048064
================
这里是A(self): <main.A object at 0x000002A70FC87FD0>
A().printself(): None
这里是A(self): <main.A object at 0x000002A70FC87FD0>
A().printself(): 140726019065984
3、@staticmethod或@classmethod的区别
- @staticmethod
- 不需要表示自身对象的self和自身类的cls参数,就跟使用函数一样
- 在@staticmethod中要调用到这个类的一些属性方法,只能直接类名.属性名或类名.方法名。
- @staticmethod只能通过A.a调用类的属性,但无法通过在该函数内部调用A.foo2()。
- @classmethod
- 也不需要self参数,但第一个参数需要是表示自身类的cls参数。
- @classmethod因为持有cls参数,可以来调用类的属性,类的方法,实例化对象等,避免硬编码。
- classmethod中可以调用类中定义的其他方法、类的属性
class A():
a=123
@classmethod
def printcls(cls):
print("A的printcls结果是:", cls)
print(A.a)
print(A().a)
A.printstatic()
A().printstatic()
A().printself()
def printself(self):
print("A的printself结果是:", self)
@staticmethod
def printstatic():
print("A的staticmethod")
a=A()
A.printcls()
》》
A的printcls结果是: <class ‘main.A’>
123
123
A的staticmethod
A的staticmethod
A的printself结果是: <main.A object at 0x0000025729EF8550>
class A():
a=123
@classmethod
def printcls(cls):
print("A的printcls结果是:", cls)
def printself(self):
print("A的printself结果是:", self)
print(A.a)
print(A().a)
A.printstatic()
A.printcls()
@staticmethod
def printstatic():
print("A的staticmethod")
a=A()
A().printself()
》》
A的printself结果是: <main.A object at 0x000002A89D457FD0>
123
123
A的staticmethod
A的printcls结果是: <class ‘main.A’>
class A():
a=123
@classmethod
def printcls(cls):
print("A的printcls结果是:", cls)
def printself(self):
print("A的printself结果是:", self)
@staticmethod
def printstatic():
print("A的staticmethod")
print(A.a)
print(A().a)
A.printcls()
A().printself()
A().printcls()
a=A()
A().printstatic()
》》
A的staticmethod
123
123
A的printcls结果是: <class ‘main.A’>
A的printself结果是: <main.A object at 0x000001C620CA84F0>
A的printcls结果是: <class ‘main.A’>
4、类中cls和self的区别:
- self是类(Class)实例化对象
- cls就是类(或子类)本身,取决于调用的是那个类
class A():
@classmethod
def printcls(cls):
print("A的printcls结果是:",cls)
def printself(self):
print("A的printself结果是:",self)
@staticmethod
def printstatic(name):
print("A的staticmethod")
a=A()
print(id(a.printcls()))
print(id(A.printcls()))》》
A的printcls结果是: <class ‘main.A’>
140726032631936
A的printcls结果是: <class ‘main.A’>
140726032631936
print(id(a.printself()))
》》
A的printself结果是: <main.A object at 0x000001A593327940>
140726032631936
》》
print(id(A.printself()))
》》
TypeError: printself() missing 1 required positional argument: ‘self’
print(id(a.printstatic()))
print(id(A.printstatic()))
》》
A的staticmethod
140726019065984
A的staticmethod
140726019065984
5、调用函数的时候有无括号的区别:
printcls不带括号时,调用的是这个函数本身,是整个函数体,不须等函数执行完成
printcls()带括号时,调用的是函数执行的结果,须等函数执行完成的结果。