Python面向对象中特殊变量main,name以及关于self的一系列问题
回过头去敲循环语句的时候,我又碰到了问题:
var = 1
while var == 1:
... num = int(input("输入一个数字 :"))
... print("你输入的数字是: ", num)
...
输入一个数字 :4
你输入的数字是: 4
输入一个数字 :7
你输入的数字是: 7
输入一个数字 :7.8
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
ValueError: invalid literal for int() with base 10: '7.8'
首先input函数永远返回一个str类型:
a=input("input: ")
input: 6
type(a)
<class 'str'>
b=input("input: ")
input: 8.9
type(b)
<class 'str'>
而Int()函数就很神奇,它可以把一个str类型或者一个number转换成一个整数:
int(3.4)
3
int('100')
100
int('2.3')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: invalid literal for int() with base 10: '2.3'
int('air')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: invalid literal for int() with base 10: 'air'
int(float('2.3'))
2
int()函数应该只能将拥有表面意义的字符串直接转化成整数,也就是说int函数是个封装,里面应该是有一个内置函数把str转化成ASCII或者别的啥我也不知道。
而int函数只能把要转化的string转化成一个十进制的数,这也就是为什么air无法转化成数字:a对应了ASCII中的97,97不在0-9之间,大于9的数对int来说就是invalid的。
为了验证猜想,可以调用int函数的另一个功能:
int(12,16)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: int() can't convert non-string with explicit base
int('12',16)
18
只有当输入是一个字符串的时候,他才能把16进制的12转化成10进制的18。因为int函数里只设置了一个内置函数(一个能将字符串转化成ASCII码之类的东西再把ASCII码转回来的函数)。
然后我开始学习了正则表达式和面向对象,正则表达式...可能因为东西太多了我没啥笔记,面向对象就还是有一点点的:
class Test:
... def ppr(self):
... print(self)
... print(self.__class__)
...
t=Test()
t.ppr()
<__main__.Test object at 0x0000019F9A9EA908>
<class '__main__.Test'>
挺简单的,就是self指一个实例,ppr这个方法里面的print(self)返回了self这个实例的地址;self.__class__则返回了一个类,可以看出Test就是那个类.main应该就是所有东西调用的地方
以__class__,__main__为代表的以双下划线为开头双下划线结尾的特殊变量(可以直接访问的变量)。__class__是什么很好理解,它指向类,在这里应当是Test这个类。然而这个__main__在查了document之后解释为:the environment where the top-level script is run. The name of the scope in which top-level code executes. A module's __name__is set equal to "__main__" when read from standard input, a script or from an interactive prompt.看上去这个__main__的出现似乎之和运行方式有关。
__name__is a built-in variable which evaluates to the name of the current module.
(大型偷懒现场)
https://stackoverflow.com/que...
https://www.geeksforgeeks.org...
https://www.journaldev.com/17...
前两个讲了__main__和以及和__name__的关系,第三个链接讲述main函数
感觉今天脑子不转了:
class A(object):
... def f(self):
... return 123
...
a=A()
print (A.f())
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: f() missing 1 required positional argument: 'self'
print (a.f())
123
第一个A.f()我以为它是一个类方法,它却返回我缺少位置参数self,self在我眼中代表了一个实例,这不是说明我缺少了一个实例作为参数,也就是说这个A.f()实际是A.f(self)而这个self需要的是一个像a一样的实例?
a.f()是一个方法,但要是前面的假设是正确的,那么它其实应该是A.f(a)
对我看到了这个:
class Test:
... def ppr():
... print(self)
...
t=Test()
t.ppr()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: ppr() takes 0 positional arguments but 1 was given
也就是说在定义ppr的时候没有给self,而t.ppr()在内部处理的时候变成了Test.ppr(t),因为没有定义参数,所以括号里并不应该给一个变量,所以出现了这个提示。
再加上self:
class Test:
... def ppr(self):
... print(self)
...
t=Test()
t.ppr()
<__main__.Test object at 0x00000241F67CB848>
t.ppr(3)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: ppr() takes 1 positional argument but 2 were given
t.ppr()=Test.ppr(t),实例地址在0x00000241F67CB848,嗯很完美
t.ppr(3)=Test.ppr(t,3),多给了一个变量,所以提示只需要一个但是给了两个。
这是问题的前一半,我留了后一半打算慢慢想,因为我试了各种组合发现如下:
class Test:
... def ppr(self):
... print(self)
...
t=Test()
Test.ppr
<function Test.ppr at 0x00000241F6792CA8>
t.ppr
<bound method Test.ppr of <__main__.Test object at 0x00000241F67CBA48>>
t.ppr()
<__main__.Test object at 0x00000241F67CBA48>
Test.ppr显然是一个类方法,但是返回了一个function,或许python中把方法当成了一种特殊函数处理(保留问题)?
t.ppr和t.ppr()返回了同一个地址但是前者返回了绑定了实例的方法的的地址,
后者加了括号,返回的是这个方法的结果,即self的地址,两个地址是相同的,也没什么问题
再试一个:
class A(object):
... def f(self):
... return 123
...
A.f
<function A.f at 0x0000027D9CE8C5E8>
A.f()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: f() missing 1 required positional argument: 'self'
a=A()
a.f
<bound method A.f of <__main__.A object at 0x0000027D9CD9C988>>
a.f()
123
a.f返回绑定了实例的方法所在地址,a.f()在这里更直观一些返回了方法的结果,也没有问题
那么今天就遗留了一个为什么A.f是一个function而不是一个method的问题。