1、 静态方法staticmethod
只是名义上归类管理,实际上再静态方法里访问不了类和实例中的任何属性
定义:
通过@staticmethod装饰器即可以把其装饰的方法变为一个静态方法,普通的方法可以在实例化之后直接调用,并且在方法里可以通过self调用实例变量或类变量,但静态方法是不可以访问实例变量或类变量。
如果按照之前学习的面向对象,写一个简单的代码如下:
class Dog(object):
def __init__(self,name):
self.name = name
def eat(self,food):
print("%s is eating %s" %(self.name,food))
d =Dog("小A")
d.eat("包子")
运行结果如下:
D:\python35\python.exe D:/python培训/s14/day7/静态方法1.py
小A is eating 包子
Process finished with exit code 0
接着对代码进行修改
class Dog(object):
def __init__(self,name):
self.name = name
@staticmethod
def eat(self,food):
print("%s is eating %s" %(self.name,food))
d = Dog("小A")
d.eat("包子")
运行结果:
D:\python35\python.exe D:/python培训/s14/day7/静态方法.py
Traceback (most recent call last):
File "D:/python培训/s14/day7/静态方法.py", line 14, in <module>
d.eat("包子")
TypeError: eat() missing 1 required positional argument: 'food'
Process finished with exit code 1
出现了如上述的错误,为了避免food参数的问题,我们再次将代码进行修改:
class Dog(object):
def __init__(self,name):
self.name = name
@staticmethod
def eat(self):
print("%s is eating %s" %(self.name,"包子"))
d = Dog("小A")
d.eat()
但是运行结果仍然出现如下错误:
D:\python35\python.exe D:/python培训/s14/day7/静态方法.py
Traceback (most recent call last):
File "D:/python培训/s14/day7/静态方法.py", line 14, in <module>
d.eat()
TypeError: eat() missing 1 required positional argument: 'self'
Process finished with exit code 1
其实这就是静态方法,这个时候eat函数和类其实没有上面关系,也可以说静态方法阶段了函数和类的关系
我们再次将代码进行更改:
class Dog(object):
def __init__(self,name):
self.name = name
@staticmethod
def eat():
print("%s is eating %s" %("小A","包子"))
d = Dog("小A")
d.eat()
运行结果如下:
D:\python35\python.exe D:/python培训/s14/day7/静态方法.py
小A is eating 包子
Process finished with exit code 0
如果非要传入参数可以将代码更改为,但是下面的代码意义不是特别大:
class Dog(object):
def __init__(self,name):
self.name = name
@staticmethod
def eat(self):
print("%s is eating %s" %(self.name,"包子"))
d = Dog("小A")
d.eat(d)
运行结果也是正常的
D:\python35\python.exe D:/python培训/s14/day7/静态方法.py
小A is eating 包子
Process finished with exit code 0
2、 类方法classmethod
类方法只能访问类变量,不能访问实例变量
我们先写如下代码
#AUTHOR:FAN
class Dog(object):
def __init__(self,name):
self.name = name
@classmethod
def eat(self):
print("%s is eating %s" %(self.name,"包子"))
d = Dog("dean")
d.eat()
运行结果出现如下错误:
D:\python35\python.exe D:/python培训/s14/day7/类方法2.py
Traceback (most recent call last):
File "D:/python培训/s14/day7/类方法2.py", line 15, in <module>
d.eat()
File "D:/python培训/s14/day7/类方法2.py", line 7, in eat
print("%s is eating %s" %(self.name,"包子"))
AttributeError: type object 'Dog' has no attribute 'name'
Process finished with exit code 1
上述显示无法调用到name
将代码进行修改
class Dog(object):
name = "AAA"
def __init__(self,name):
self.name = name
@classmethod
def eat(self):
print("%s is eating %s" %(self.name,"包子"))
d = Dog("dean")
d.eat()
运行效果如下:
D:\python35\python.exe D:/python培训/s14/day7/类方法2.py
AAA is eating 包子
Process finished with exit code 0
从上面的运行结果可以看出虽然我实例化的时候传入了dean但是确实类变量AAA
3、属性方法property
将一个方法变成一个静态属性
我们先写如下代码:
class Dog(object):
def __init__(self,name):
self.name = name
@property
def eat(self):
print("%s is eating %s" %(self.name,"包子"))
d = Dog("dean")
d.eat()
运行结果如下:
D:\python35\python.exe D:/python培训/s14/day7/属性方法2.py
dean is eating 包子
Traceback (most recent call last):
File "D:/python培训/s14/day7/属性方法2.py", line 9, in <module>
d.eat()
TypeError: 'NoneType' object is not callable
Process finished with exit code 1
所以我将代码进行修改(将d.eat()改为d.eat):
#AUTHOR:FAN
class Dog(object):
def __init__(self,name):
self.name = name
@property
def eat(self):
print("%s is eating %s" %(self.name,"包子"))
d = Dog("dean")
d.eat
运行结果如下:
D:\python35\python.exe D:/python培训/s14/day7/属性方法2.py
dean is eating 包子
Process finished with exit code 0
从上面可以看出将一个方法变成一个静态属性
但是这个时候也同样发现无法传参数了。并且及时是已经是一个静态属性了,也是不能赋值的
如果想要赋值,可以将代码进行如下修改:
class Dog(object):
def __init__(self,name):
self.name = name
self.__food = None
@property
def eat(self):
print("%s is eating %s" %(self.name,self.__food))
@eat.setter
def eat(self,food):
print("set to food:",food)
self.__food = "包子"
d = Dog("dean")
d.eat
d.eat="包子"
d.eat
运行结果如下:
D:\python35\python.exe D:/python培训/s14/day7/属性方法2.py
dean is eating None
set to food: 包子
dean is eating 包子
Process finished with exit code 0
这样通过上面的方法就可以对其作为属性进行赋值修改
但是默认情况下属性方法是无法删除的,如果想要删除,需要:
#AUTHOR:FAN
class Dog(object):
def __init__(self,name):
self.name = name
self.__food = None
@property
def eat(self):
print("%s is eating %s" %(self.name,self.__food))
@eat.setter
def eat(self,food):
print("set to food:",food)
self.__food = "包子"
@eat.deleter
def eat(self):
del self.__food
print("删完了")
d = Dog("dean")
d.eat
d.eat="包子"
d.eat
del d.eat
运行结果如下:
D:\python35\python.exe D:/python培训/s14/day7/属性方法2.py
dean is eating None
set to food: 包子
dean is eating 包子
删完了
Process finished with exit code 0
4、 类的特殊成员方法
__doc__表示类的描述信息
__module__表示当前操作的对象在哪个模块
__class__表示当前操作的对象的类是什么
__init__构造方法,通过类创建对象时,自动触发执行
__del__ 析构函数,当对象在内存中释放时,自动触发执行
__call__对象后面加括号,触发执行
代码例子:
class Dog(object):
def __init__(self,name):
self.name = name
# @staticmethod
def eat(self,food):
print("%s is eating %s" %(self.name,food))
def __call__(self, *args, **kwargs):
print("running call",args,kwargs)
d = Dog("小A")
d(1,2,3,4,name="dean")
运行结果如下:
D:\python35\python.exe D:/python培训/s14/day7/静态方法.py
running call (1, 2, 3, 4) {'name': 'dean'}
Process finished with exit code 0
__dict__查看类或对象中的所有成员
代码例子:
class Dog(object):
def __init__(self,name):
self.name = name
# @staticmethod
def eat(self,food):
print("%s is eating %s" %(self.name,food))
def __call__(self, *args, **kwargs):
print("running call",args,kwargs)
d = Dog("小A")
# d(1,2,3,4,name="dean")
print(Dog.__dict__)
print(d.__dict__)
运行结果如下:
D:\python35\python.exe D:/python培训/s14/day7/静态方法.py
{'__doc__': None, 'eat': <function Dog.eat at 0x0000000000B6E378>, '__init__': <function Dog.__init__ at 0x0000000000B6E2F0>, '__weakref__': <attribute '__weakref__' of 'Dog' objects>, '__call__': <function Dog.__call__ at 0x0000000000B6E400>, '__dict__': <attribute '__dict__' of 'Dog' objects>, '__module__': '__main__'}
{'name': '小A'}
Process finished with exit code 0
从上面例子也可以看出print(Dog.__dict__)打印类里的所有属性,不包括实例属性
print(d.__dict__)打印所有实例属性,不包括类属性
__str__如果一个类中定义了__str__方法,那么在打印对象时,默认输出该方法的返回值
__getitem__ __setitem__ __telitem__
用于索引操作,如字典。以上分别表示获取,设置、删除数据
__new__
代码如下:
class Foo(object):
def __init__(self,name):
self.name = name
f = Foo("dean")
print(type(f))
print((type(Foo)))
在上述代码中f是通过Foo实例化的对象,其实不仅f是一个对象,Foo类本身也是一个对象,因为在python中一切事物都是对象
运行结果如下:
D:\python35\python.exe D:/python培训/s14/day7/__new__.py
<class '__main__.Foo'>
<class 'type'>
Process finished with exit code 0
上面的输出同样表示了:
所以从上面也可以得出f对象时Foo类的一个实例,Foo类对象时type类的一个实例,即Foo类对象时通过type类构造方法创建的
所以创建类就可以有两种方法:
普通方法
class Foo(object):
def func(self):
print("hello dean")
特殊方法
def func(self):
print("hello dean")
Foo = type('Foo',(object,),{'talk':func})
f = Foo()
f.talk()
print(type(Foo))
运行结果如下:
D:\python35\python.exe D:/python培训/s14/day7/__new__.py
hello dean
<class 'type'>
Process finished with exit code 0
从这里也可以看出type就是类的类,所有的类都是通过type创建的
将上述代码进行修改:
def func(self):
print("hello dean")
def __init(self ,name,age):
self.name = name
self.age = age
Foo = type('Foo',(object,),{'talk':func,
'__init__':__init})
f = Foo("dean",23)
print(f.name)
print(f.age)
f.talk()
print(type(Foo))
运行结果如下:
D:\python35\python.exe D:/python培训/s14/day7/__new__.py
dean
23
hello dean
<class 'type'>
Process finished with exit code 0
5、 反射
getattr(obj,name_str)判断一个对象obj里是否有对应name_str的字符串的方法映射
getattr(obj,name_str) 根据字符串去获取obj对象里的对应的方法的内存地址
代码例子:
class Dog(object):
def __init__(self,name):
self.name = name
def eat(self):
print("%s is eating..." %self.name)
d = Dog("dean")
choice = input(">>>:").strip()
#
# print(hasattr(d,choice))
# print(getattr(d,choice))
#
# getattr(d,choice)()
if hasattr(d,choice):
func = getattr(d,choice)
func()
运行结果如下:
D:\python35\python.exe D:/python培训/s14/day7/反射1.py
>>>:eat
dean is eating...
Process finished with exit code 0
如果输入的字符串对应的方法不存在的情况让添加外面的类:代码如下,
def bulk(self):
print("%s is yelling....." %self.name)
class Dog(object):
def __init__(self,name):
self.name = name
def eat(self):
print("%s is eating..." %self.name)
d = Dog("dean")
choice = input(">>>:").strip()
if hasattr(d,choice):
func = getattr(d,choice)
func()
else:
setattr(d,choice,bulk)
d.talk(d)
运行结果如下:
D:\python35\python.exe D:/python培训/s14/day7/反射1.py
>>>:talk
dean is yelling.....
Process finished with exit code 0
setattr(obj,’y’,z) 相当于x.y = v
代码例子:
if hasattr(d,choice):
func = getattr(d,choice)
func()
else:
setattr(d,choice,22)
print(getattr(d,choice))
删除是delattr(d,choice)
6、异常处理
语法:
try:
pass
except Exception as e:
pass
一个简单的例子:
name =[1,2,3]
try:
name[4]
except IndexError as e:
print(e)
如果想要同时抓多个错误的方法:
try:
code
except(Error1,Error2) as e:
print(e)
如果想要一次性抓住所有错误可以用Exceptions(一般不用,无法定位错误,但是一般放到最后面,用于提示未知错误):
name =[1,2,3]
try:
name[4]
except Exceptions e:
print(e)
else 表示一切正常
finally 表示不管有没有错都执行
一些常见的异常:
AttributeError 试图访问一个对象没有的树形,比如foo.x,但是foo没有属性x
IOError 输入/输出异常;基本上是无法打开文件
ImportError 无法引入模块或包;基本上是路径问题或名称错误
IndentationError 语法错误(的子类) ;代码没有正确对齐
IndexError 下标索引超出序列边界,比如当x只有三个元素,却试图访问x[5]
KeyError 试图访问字典里不存在的键
KeyboardInterrupt Ctrl+C被按下
NameError 使用一个还未被赋予对象的变量
SyntaxError Python代码非法,代码不能编译(个人认为这是语法错误,写错了)
TypeError 传入对象类型与要求的不符合
UnboundLocalError 试图访问一个还未被设置的局部变量,基本上是由于另有一个同名的全局变量,
导致你以为正在访问它
ValueError 传入一个调用者不期望的值,即使值的类型是正确的
自定义异常代码例子:
class myerror(Exception):
def __init__(self, msg):
self.message = msg
try:
name = []
name = [3]
raise myerror('我的异常')
except myerror as e:
print(e)
运行结果如下:
D:\python35\python.exe D:/python培训/s14/day7/自定义异常.py
我的异常
Process finished with exit code 0
7、 socket编程
一个简单的例子:
服务端:
import socket
server = socket.socket()
server.bind(('127.0.0.1',6969)) #绑定要监听的端口
server.listen()#监听
print("我要开始等电话了")
#conn就是客户端连过来而在服务器端为其生成的一个连接实例
conn,addr = server.accept()#等待电话打来
print("电话来了")
data = conn.recv(1024)
print("recv:",data)
conn.send(data.upper())
server.close()
客户端:
import socket
client = socket.socket()
client.connect(('127.0.0.1',6969))
client.send(b"Hello world")
data = client.recv(1204)
print("recv:",data)
client.close()
先运行服务端,在运行客户端,结果如下:
D:\python35\python.exe D:/python培训/s14/day7/socket_server1.py
我要开始等电话了
电话来了
recv: b'Hello world'
Process finished with exit code 0
D:\python35\python.exe D:/python培训/s14/day7/socket_client1.py
recv: b'HELLO WORLD'
Process finished with exit code 0
将上述代码进行改进:
服务端:
import socket
server = socket.socket()
server.bind(('127.0.0.1',6969)) #绑定要监听的端口
server.listen()#监听
print("我要开始等电话了")
while True:
# conn就是客户端连过来而在服务器端为其生成的一个连接实例
conn, addr = server.accept() # 等待电话打来
print("电话来了")
while True:
data = conn.recv(1024)
print("recv:",data)
if not data:
print("client has lost....")
break
conn.send(data.upper())
server.close()
客户端:
import socket
client = socket.socket()
client.connect(('127.0.0.1',6969))
while True:
msg = input(">>:").strip()
client.send(msg.encode("utf-8"))
data = client.recv(1204)
print("recv:",data.decode())
client.close()
上述代码改进后可以在客户端断开后,服务端不会进入死循环没如果这个时候有新的客户端进入,可以继续通讯