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