Dayday up ---- python Day7
面向对象静态方法:
@staticmethod
把方法和类的关系截断了,只是在调用的时候需要类来调用,名义上归类管理,实际上在静态方法里访问不了类或实例中的任何属性
没有加静态方法之前:
class Dog(object):
def __init__(self,name):
self.name = name
def eat(self):
print("%s is eating..." % self.name)
d = Dog("小七")
d.eat()
添加静态方法之后:
eat需要一个self参数,但调用时却没有传递,当eat变成静态方法后,再通过实例调用时就不会自动把实例本身当作一个参数传给self了。
class Dog(object):
def __init__(self,name):
self.name = name
@staticmethod
def eat(self):
print("%s is eating..." % self.name)
d = Dog("小七")
d.eat()
报错:
Traceback (most recent call last):
File "F:/python3/day7/staticmethod_file.py", line 15, in <module>
d.eat()
TypeError: eat() missing 1 required positional argument: 'self'
1. 调用时主动传递实例本身给eat方法,即d.eat(d)
2. 在eat方法中去掉self参数,但这也意味着,在eat中不能通过self.调用实例中的其它变量了
正确:
class Dog(object):
def __init__(self,name):
self.name = name
@staticmethod
def eat(self):
print("%s is eating..." % self.name)
d = Dog("小七")
d.eat(d)
面向对象类方法:
@classmethod
只能访问类变量,不能访问实例变量
当eat变成类方法之后:
class Dog(object):
def __init__(self,name):
self.name = name
@classmethod
def eat(self):
print("%s is eating..." % self.name)
d = Dog("小七")
d.eat()
报错:
Traceback (most recent call last):
File "F:/python3/day7/classmethod_file.py", line 13, in <module>
d.eat()
File "F:/python3/day7/classmethod_file.py", line 9, in eat
print("%s is eating..." % self.name)
AttributeError: type object 'Dog' has no attribute 'name'
正确:
可以定义一个类变量,也叫name
class Dog(object):
name = "花花儿"
def __init__(self,name):
self.name = name
@classmethod
def eat(self):
print("%s is eating..." % self.name)
d = Dog("小七")
d.eat()
执行结果:
花花儿 is eating...
面向对象属性方法
@property
属性方法的作用就是通过@property把一个方法变成一个静态属性
当eat变成属性方法之后:
class Dog(object):
def __init__(self,name):
self.name = name
@property
def eat(self):
print("%s is eating..." % self.name)
d = Dog("小七")
d.eat()
报错:
Traceback (most recent call last):
File "F:/python3/day7/property_file.py", line 14, in <module>
d.eat()
TypeError: 'NoneType' object is not callable
因为eat此时已经变成一个静态属性了, 不是方法了, 想调用已经不需要加()号了,直接d.eat就可以了
正确:
class Dog(object):
def __init__(self,name):
self.name = name
@property
def eat(self):
print("%s is eating..." % self.name)
d = Dog("小七")
d.eat
结果:
小七 is eating...
修改属性和删除属性
class Dog(object):
def __init__(self,name):
self.name = name
@property
def eat(self):
print("%s is eating..." % self.name)
@eat.setter #修改属性
def eat(self,food):
self.__food = food
print("set to food:", self.__food)
@eat.deleter #删除属性
def eat(self):
del self.__food
print("删完了")
# print(self.__food)
d = Dog("小七")
# d.eat
d.eat = "water" #触发 @eat.setter
del d.eat #触发 @eat.deleter
属性方法例子:
# --*--coding:utf-8--*--
class Flight(object):
def __init__(self,name):
self.flight_name = name
def checking_status(self):
print("checking flight %s status " % self.flight_name)
return 1
@property
def flight_status(self):
status = self.checking_status()
if status == 0 :
print("flight got canceled...")
elif status == 1 :
print("flight is arrived...")
elif status == 2:
print("flight has departured already...")
else:
print("cannot confirm the flight status...,please check later")
@flight_status.setter
def flight_status(self,status):
status_dic = {
0: "canceled",
1: "arrived",
2: "departured"
}
print("\033[31;1mHas changed the flight status to \033[0m",status_dic.get(status))
@flight_status.deleter
def flight_status(self):
print("status got removed...")
f = Flight("CA980")
f.flight_status
f.flight_status = 2
del f.flight_status
类的特殊成员方法:
1、__doc__ 表示类的描述信息
class Foo:
'''描述类信息,welcome'''
def func(self):
print("hello")
print(Foo.__doc__)
结果:
描述类信息,welcome
2、__module__ 输出模块
3、__class__ 输出类
from lib.aa import C obj = C() print(obj.__module__) print(obj.__class__) 结果: lib.aa <class 'lib.aa.C'>
4、__init__ 构造方法,通过类创建对象时,自动触发执行。
5、__del__ 析构方法,当对象在内存中被释放时,自动触发执行。
析构函数的调用是由解释器在进行垃圾回收时自动触发执行的
6、 __call__ 对象后面加括号,触发执行
构造方法的执行是由创建对象触发的,即:对象 = 类名() ;而对于 __call__ 方法的执行是由对象后加括号触发的,即:对象() 或者 类()()
class men(object):
def __init__(self,name):
self.name = name
def talk(self):
print("%s is talking..." % self.name)
def __call__(self, *args, **kwargs):
print("running call %s" % self.name)
m = men("hh")
m()
结果:
running call hh
7、__dict__ 查看类或对象中的所有成员
class men(object):
def __init__(self,name,age):
self.name = name
self.age = age
def talk(self):
print("%s is talking..." % self.name)
def __call__(self, *args, **kwargs):
print("running call %s" % self.name)
m = men("hh",22)
print(men.__dict__)
#结果:
# {'__init__': <function men.__init__ at 0x0000000000A2F268>, '__dict__': <attribute '__dict__' of 'men' objects>, '__module__': '__main__',
print(m.__dict__)
#结果:
# {'name': 'hh', 'age': 22}
8、__str__ 如果一个类中定义了__str__方法,那么在打印 对象 时,默认输出该方法的返回值。
class Foo(object):
def __init__(self,name):
self.name = name
def __str__(self):
return ("%s, hello, girls~~~~" % self.name)
obj = Foo("yy")
print(obj)
结果:
yy, hello, girls~~~~
9、__getitem__、__setitem__、__delitem__
用于索引操作,如字典。以上分别表示获取、设置、删除数据
class Foo(object):
def __init__(self):
self.data = {}
def __getitem__(self, key):
print('__getitem__', key)
return self.data.get(key)
def __setitem__(self, key, value):
print('__setitem__', key, value)
self.data[key] =value
def __delitem__(self, key):
print('__delitem__', key)
obj = Foo()
result = obj['k1'] # 自动触发执行 __getitem__
obj['k2'] = 'alex' # 自动触发执行 __setitem__
del obj['k1'] # 自动触发 __delitem__
10、__new__ \ __metaclass__
首先追溯类的起源
class Foo(object):
def __init__(self,name):
self.name = name
f = Foo("ll")
print(type(f))
#结果
#<class '__main__.Foo'>
print(type(Foo))
#结果
#<class 'type'>
从上面的例子可以看出: 类的起源,底层通过type,类的起源是type,而type的起源是解释器 即 类对象 是通过type类的构造方法创建。
#创建类的特殊方法
def func(self):
print("hello girl! , %s" % self.name)
def __init__(self,name):
self.name = name
Foo = type('Foo',(object,),{'func':func,'__init__':__init__})
f = Foo("yy")
f.func()
#结果
# hello girl! , yy
__new__ 是类里面自带的方法,可以重构,在实例化的时候会执行,并且会在__init__之前执行
通过__new__来实例化,先走__new__ 在调用__init__
class MyType(type):
def __init__(self, what, bases=None, dict=None): #第一步
print("--MyType init---")
super(MyType, self).__init__(what, bases, dict)
def __call__(self, *args, **kwargs): #第二步
print("--MyType call---")
obj = self.__new__(self, *args, **kwargs)
obj.data = {"name":111}
self.__init__(obj, *args, **kwargs)
class Foo(object): #第四步
__metaclass__ = MyType #不是继承,用来定义这个类是以怎样的形式被创建
def __init__(self, name):
self.name = name
print("Foo ---init__")
def __new__(cls, *args, **kwargs): #第三步
print("Foo --new--")
#print(object.__new__(cls))
return object.__new__(cls) #继承父亲的__new__方法
# 第一阶段:解释器从上到下执行代码创建Foo类
# 第二阶段:通过Foo类创建obj对象
obj = Foo("ll")
print(obj.name)
反射
通过字符串映射或修改程序运行时的状态、属性、方法,
1、hasattr(obj,name_str)
判断object中有没有一个name字符串对应的方法或属性
2、getattr(obj,name_str)
根据字符串获取obj对象里对应的方法内存地址
3、setattr(obj,str,value)
通过字符串设置新的属性
4、delattr(obj,str)
删除属性
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("小七")
choice = input(">>:").strip()
# 判断
if hasattr(d,choice):
func_eat = getattr(d,choice)
func_eat()
else:
setattr(d,choice,bulk) #d.talk = bulk
func = getattr(d, choice)
func(d)
# print(hasattr(d,"bulk")) #检查是否有bulk方法
# # False
# print(hasattr(d,"eat")) #检查是否有eat方法
# # True
# getattr(d, 'eat') #获取eat方法
# setattr(d,"bulk",bulk) #设置bulk方法
# func = getattr(d,"bulk")
# func(d)
异常处理
例1:
data = {}
names = []
try:
# data['name']
names[3]
except KeyError as e: #抓住KeyError错误
print("没有这个key:",e)
except IndexError as e: #抓住IndexError错误
print("列表操作错误",e)
例2:
while True:
num1 = input("num1:")
num2 = input("num2:")
try:
num1 = int(num1)
num2 = int(num2)
result = num1 + num2
print("结果是:", result)
except Exception as e: #抓住所有的错误,万能异常
print("出现异常:",e)
else: #如果没有错误则执行
print("一切正常")
finally: #不管有没有错误,都执行
print("无论结果怎样,都执行.")
但是缩进以及语法错误类似错误无法抓取
如果错误的处理方法一样,可以这么写:
except (KeyError,IndexError) as e:
print("没有这个key:",e)
常用异常
AttributeError 试图访问一个对象没有的树形,比如foo.x,但是foo没有属性x IOError 输入/输出异常;基本上是无法打开文件 ImportError 无法引入模块或包;基本上是路径问题或名称错误 IndentationError 语法错误(的子类) ;代码没有正确对齐 IndexError 下标索引超出序列边界,比如当x只有三个元素,却试图访问x[5] KeyError 试图访问字典里不存在的键 KeyboardInterrupt Ctrl+C被按下 NameError 使用一个还未被赋予对象的变量 SyntaxError Python代码非法,代码不能编译(个人认为这是语法错误,写错了) TypeError 传入对象类型与要求的不符合 UnboundLocalError 试图访问一个还未被设置的局部变量,基本上是由于另有一个同名的全局变量, 导致你以为正在访问它 ValueError 传入一个调用者不期望的值,即使值的类型是正确的
主动触发异常:
try:
raise KeyError("没有这个key")
except KeyError as e:
print(e)
自定义异常:
class llException(Exception):
def __init__(self,msg):
self.msg = msg
def __str__(self):
return ("报错啦: %s ") % self.msg
try:
raise llException("我的异常")
except llException as e:
print(e)
结果:
报错啦: 我的异常
socket 网络编程
socket通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄,应用程序通常通过"套接字"向网络发出请求或者应答网络请求
socket模块是针对 服务器端 和 客户端Socket 进行【打开】【读写】【关闭】
例子:
import socket client = socket.socket() # 声明socket类型,同时生成socket连接对象 client.connect(('localhost',6969)) client.send(b"hello World!") data = client.recv(1024) client.close()
import socket server = socket.socket() server.bind(('localhost',6969)) server.listen() #监听 print("我要开始等电话了") conn,addr = server.accept() # 等待电话进来 # conn 就是客户端连过来而在服务器端为其生成的一个连接实例 print(conn,addr) print("电话来了") data = conn.recv(1024) print("recv:",data) conn.send(data.upper()) server.close()

浙公网安备 33010602011771号