这是一段Python代码,它定义了几个类和它们的方法。以下是对每个类和函数的详细解释:
person类:这是一个基础类,用于表示一个人。它有一个初始化方法__init__,该方法接受一个参数name,并将其赋值给类的name属性。
python
复制
class person():
def __init__(self, name):
self.name = name
skillMixin类:这是一个混合类(Mixin),用于添加技能相关的功能。它也有一个初始化方法__init__,接受一个参数skil,并将其赋值给类的skill属性。
python
复制
class skillMixin():
def __init__(self, skil):
self.skill = skil
basketballMixin类:这是一个继承自skillMixin的类,专门用于表示篮球技能。它重写了父类的skill方法,打印出字符串'basketball'。
python
复制
class basketballMixin(skillMixin):
def skill(self):
print('basketball')
student类:这是一个继承自person的类,用于表示学生。它重写了父类的初始化方法__init__,以确保调用父类的初始化方法。
python
复制
class student(person):
def __init__(self, name):
super(student, self).__init__(name)
Bstudent类:这是一个同时继承自basketballMixin和student的类,用于表示会打篮球的学生。它没有定义额外的方法或属性,因此它继承了其父类的所有功能。
python
复制
class Bstudent(basketballMixin, student):
pass
在代码的末尾,注释掉的部分创建了一个Bstudent类的实例s,并尝试调用它的skil()方法(应该是skill()方法)。如果取消注释,这段代码会创建一个学生实例,并打印出'basketball',因为Bstudent类继承了basketballMixin类的skill方法。
总结来说,这段代码展示了Python中类和混合类的定义,以及如何通过继承来组合不同的类和功能。
代码定义了一个名为Person的类,它使用__slots__属性来限制可以动态添加的实例属性。在这个例子中,Person类只有两个属性:name和gender。__init__方法是构造方法,用于初始化这些属性。
接着,代码定义了一个名为Student的类,它继承自Person类。Student类同样使用__slots__来限制实例属性,这里添加了一个额外的属性score。Student类的__init__方法不仅初始化了从Person类继承来的name和gender属性,还初始化了score属性。
在代码的最后,创建了一个Student类的实例s,并给它的name属性赋值为'Tim',score属性赋值为99。然后,通过s.score打印出实例s的score属性值。
这是一个面向对象编程的例子,展示了类的继承和实例化,以及如何通过实例来访问类中定义的属性。
int()函数可以把字符串转换为整数,当仅传入字符串时,int()函数默认按十进制转换;int()函数还提供额外的base参数,如果传入base参数,就可以做 N 进制的转换。
>>> int('12345', base=8) 5349
functools.partial就是帮助我们创建一个偏函数的,不需要我们自己定义int2(),可以直接使用下面的代码创建一个新的函数int2:
>>> import functools >>> int2 = functools.partial(int, base=2) >>> int2('1000000') 64
@log('DEBUG') def my_func(): pass
my_func = log('DEBUG')(my_func)
log_decorator = log('DEBUG') my_func = log_decorator(my_func)
log_decorator = log('DEBUG') @log_decorator def my_func(): pass
带参数的log函数首先返回一个decorator函数,再让这个decorator函数接收my_func并返回新函数,相当于是在原有的二层嵌套里面,增加了一层嵌套.
def log(prefix): def log_decorator(f): def wrapper(*args, **kw): print('[{}] {}()...'.format(prefix, f.__name__)) return f(*args, **kw) return wrapper return log_decorator @log('DEBUG') def test(): pass test()
Python的 decorator 本质上就是一个高阶函数,它接收一个函数作为参数,然后,返回一个新函数。
使用 decorator 用Python提供的 @ 语法,这样可以避免手动编写 f = decorate(f) 这样的代码。
要让 @log 自适应任何参数定义的函数,可以利用Python的 args 和 *kwargs,保证任意个数的参数总是能正常调用.
def log(f): def fn(*args, **kwargs): print('call ' + f.__name__ + '()...') return f(*args, **kwargs) return fn
@log def factorial(n): return reduce(lambda x,y: x*y, range(1, n+1)) print(factorial(10))
内层函数引用了外层函数的变量(参数也算变量),然后返回内层函数的情况,称为闭包(Closure)。
闭包的特点是返回的函数还引用了外层函数的局部变量,所以,要正确使用闭包,就要确保引用的局部变量在函数返回后不能变。
def calc_sum(list_): def lazy_sum(): return sum(list_) return lazy_sum
返回函数和返回函数值的语句是非常类似的,返回函数时,不能带小括号,而返回函数值时,则需要带上小括号以调用函数。
# 返回函数 def myabs(): return abs # 返回函数值 def myabs(x): return abs(x)
需要指定排序的字段是成绩,sorted接受key参数,用来指定排序的字段,key的值是一个函数,接受待排序列表的元素作为参数,并返回对应需要排序的字段。
def k(item): return item[1] # ==> 按成绩排序,成绩是第二个字段 sorted(score, key=k)
filter()函数是 Python 内置的另一个有用的高阶函数,filter()函数接收一个函数 f 和一个list,这个函数 f 的作用是对每个元素进行判断,返回 True或 False,filter()根据判断结果自动过滤掉不符合条件的元素,并返回一个迭代器,可以迭代出所有符合条件的元素。
def is_odd(x): return x % 2 == 1 for item in filter(is_odd, [1, 4, 6, 7, 9, 12, 17]): print(item)
reduce()函数接收的参数和 map() 类似,一个函数 f,一个list,但行为和 map()不同,reduce()传入的函数 f 必须接收两个参数,reduce()对list的每个元素反复调用函数f,并返回最终结果值。
map()是 Python 内置的高阶函数,它接收一个函数 f 和一个 list,并通过把函数 f依次作用在list的每个元素上,map()函数会返回一个迭代器,可以依次迭代得到原来list的元素被函数f处理后的结果。
map(f, list)
在Python中,使用套接字socket来建立起网络连接。
服务端建立需要四个步骤:新建socket、绑定IP和端口(bind)、监听连接(listen)、接受连接(accept)。
客户端仅需两个步骤:新建socket、连接服务端(connect)。
当网络连接上以后,客户端和服务端就可以进行数据通信了,套接字通过send()函数发送数据,通过recv()函数接收数据。
import socket server = socket.socket() # 1. 新建socket server.bind(('127.0.0.1', 8999)) # 2. 绑定IP和端口(其中127.0.0.1为本机回环IP) server.listen(5) # 3. 监听连接 s, addr = server.accept() # 4. 接受连接 print('connect addr:{}'.format(addr)) content =s.recv(1024) print(str(content, encoding='utf-8')) # 接受来自客户端的消息,并编码打印出来 s.close()
import socket client = socket.socket() # 1. 新建socket client.connect(('127.0.0.1', 8999)) # 2. 连接服务端(注意,IP和端口要和服务端一致) client.send(bytes('Hello World. Hello Socket', encoding='utf-8')) # 发送内容,注意发送的是字节字符串。 client.close()
python server.py python client.py
seek()方法,可以移动文件的游标位置,它接受一个参数,表示文件的位置,0:文件首部,1:当前位置,2:文件尾部,通过seek()可以把文件游标移动到文件首部但不删除文件的内容。
从模块中导入函数并将其重命名:
from ... import as ... from math import pow as mathpow
__slots__的目的是限制当前类所能拥有的属性.
class Person(object): def __init__(self,name): self.name = name p = Person('lily') p.age = 12 class Student(object): __slots__ = ('name','gender') def __init__(self,name,gender): self.name = name self.gender s = Student('Tom','Male') s.age = 10 print(s.age) #会出错
dir()返回的是属性是字符串列表;
通过getattr()和setattr()来获取或设置对象属性;
通过type()获得变量类型。
i = 10 type(i) dir(i) class Person(object): def __init__(self,name,age,**kwargs): self.name = name self.age = age for k,v in kwargs.items(): setattr(self,k,v)
多重继承,初始化方法只调用一次;
多重继承的目的是从多种继承树选择并继承出子类,以便组合功能使用。
class D(object): pass class A(D): pass class MK(object): pass class Ck(MK): pass class Ack(A,Ck): pass
定义继承类:
1.定义子类,在括号里写明要继承的父类;
2.初始化方法,需要调用super(子类,self).__init__(继承的属性).
class Person(object): def __init__(self,name,gender): self.name = name self.gender = gender class Teacher(Person): def __init__(self,name,gender,subject): super(Teacher,self).__init__(name,gender) self.subject = subject
1.类方法需要使用@classmethod来标记为类方法,否则定义的还是实例方法;
2.类方法的第一个参数将传入类本身,通常将参数名命名为 cls.
class Animal(object): __count = 0 def __init__(self,name,age): self.name = name self.age = age Animal.__count += 1 @classmethod def get_count(cls): return cls.__count
访问私有属性,可通过类中定义实例方法。
class Animal(object): def __init__(self,name,age,location): self.__name = name self.__age = age self.__location = location def get_info(self): return 'name = {}, age = {}, location = {}'.format(self.__name,self.__age,self.__location)
不被外部访问的属性为私有属性,类属性或实例属性均不能对其访问。私有属性定义以双下划线“__”开头。
class Animal(object): def __init__(self,name,age): self.name = name self.__age = age dog = Animal('Tom',3) print(dog.__age) #会报错
面向对象编程:属性 、 类 、 实例。
1、解释下什么是面向对象编程
class Person(object):
__slots__ = ('name', 'gender')
def __init__(self, name, gender):
self.name = name
self.gender = gender
class Student(Person):
__slots__ = ('score',)
def __init__(self, name, gender, score):
self.name = name
self.gender = gender
self.score = score
s = Student('Bob', 'male', 59)
s.name = 'Tim'
s.score = 99
print(s.score)
注:__slots__ = ('name', 'gender') 限定属性,不能动态添加属性
通过type()函数,可以获得变量的类型。
通过dir()方法,可以获取变量的所有属性:在dir列出的属性中,有很多是以下划线开头和结尾的,这些都是特殊的方法,称为内建方法,如果已知一个属性名称,要获取或者设置对象的属性,就需要用 getattr() 和 setattr( )函数了。
>>> getattr(p, 'name') # 获取name属性
'Alice'
>>> setattr(p, 'name', 'Adam') # 设置新的name属性
>>> s.name
'Adam'
函数isinstance()可以判断一个变量的类型。
>>> isinstance(s, Person)
True # s是Person类型
>>> isinstance(s, Student)
True # s是Student类型
>>> isinstance(s, Teacher)
False # s不是Teacher类型
对人类的抽象可以定义为Person类,而学生、老师等,也都是人类,所以,在Python当中,如果定义学生Student的类,可以继承Person类。
接着定义Student类,在定义Student类的时候,由于继承了Person类,所以Student类自动拥有name、gender属性,因此,在定义Student类的时候,只需要把额外的属性加上即可。
class Student(Person):
def __init__(self, name, gender, score):
super(Student, self).__init__(name, gender)
self.score = score
student = Student('Alice', 'girl', 100)
print(student.name) # ==> Alice
print(student.gender) # ==> girl
print(student.score) # ==> 100
在定义继承类的时候,有几点是需要注意的:
1. class Student()定义的时候,需要在括号内写明继承的类Person
2. 在__init__()方法,需要调用super(Student, self).__init__(name, gender),来初始化从父类继承过来的属性
为了操作实例对象的私有属性,我们定义了实例方法;同样的,如果需要需要操作类的私有属性,则应该定义类的方法。
默认的,在class中定义的全部是实例方法,实例方法第一个参数 self 是实例本身。
要在class中定义类方法,需要这么写:
class Animal(object):
__localtion = 'Asia'
def __init__(self, name, age):
self.name = name
self.age = age
@classmethod
def set_localtion(cls, localtion):
cls.__localtion = localtion
@classmethod
def get_localtion(cls):
return cls.__localtion
print(Animal.get_localtion()) # ==> Asia
Animal.set_localtion('Afica')
print(Animal.get_localtion()) # ==> Africa
和实例方法不同的是,这里有两点需要特别注意:
类方法需要使用@classmethod来标记为类方法,否则定义的还是实例方法
类方法的第一个参数将传入类本身,通常将参数名命名为 cls,上面的 cls.__localtion 实际上相当于Animal.__localtion。
因为是在类上调用,而非实例上调用,因此类方法无法获得任何实例变量,只能获得类的引用。
总结:
实例方法def 方法(self,); 类方法def 方法(cls),且前面须加上@classmethod。
类方法只能访问类变量引用,不能访问实例内的变量。
把Animal类的age、name、localtion定义成私有属性,并定义对应的方法修改和获取他们的值。
class Animal(object):
def __init__(self, name, age, localtion):
self.__name = name
self.__age = age
self.__localtion = localtion
def set_name(self, name):
self.__name = name
def get_name(self):
return self.__name
def set_age(self, age):
self.__age = age
def get_age(self):
return self.__age
def set_localtion(self, localtion):
self.__localtion =localtion
def get_localtion(self):
return self.__localtion
p=Animal("ww","12","we")
print(p.get_name(),p.get_age(),p.get_localtion())
注:本例中如果去除def set_name(self, name):等,程序也能正常运行,待解。
def get_info(self):
return 'name = {}, age = {}, localtion = {}'.format(self.name, self.age, self.localtion)
这个语句可以同时取得多个属性