python解惑:cls和self的区别、创建类时加不加括号区别、调用函数有无括号区别

python学习过程中经常遇到cls、self有什么区别,类和函数带不带括号什么区别,创建类带不带括号有什么区别,这里打算汇总一下

1、创建类时加不加括号的区别:

class Apass

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()带括号时,调用的是函数执行的结果,须等函数执行完成的结果。


版权声明:本文为jq656021898原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。