类:具有相同属性和技能的一类事物
对象:就是类的具体表现,具体是实例
让对象与对象发生关系
1. super().父类方法名(参数(自传self))
2. 父类名.父类方法名(参数)
查询类的继承顺序:类名.mro()
# 1.操作静态字段
# 1 查询类中的全都内容
__dict__
# 2. 万能的点
# 3. 增删改查
# 2.操作类的方法(除了类方法,静态方法需要类名调用之外。剩下的方法都要对象调用)
# 操作静态字段
# 1. 查询对象空间全部的内容 print(obj.__dict__) {'name': 'ALEX', 'age': 100}
# 2. 万能的点
# 操作类的方法
# obj.func() 对象.方法名
# 1. 创建了一个对象空间,实例空间
# 2. 自动执行 __init__ 方法,并将我的对象空间传给self
# 3. 执行具体的 __init__ 代码,给对象空间封装属性
class A:
name = []
p1 = A()
p2 = A()
p1.name.append(1)
# p1.name,p2.name,A.name 分别是什么?
print(p1.name) #[1]
print(p2.name) #[1]
print(A.name) #[1]
class Payment(metaclass=ABCMeta): # 抽象类(接口类):
@abstractmethod
def pay(self): pass # 制定了一个规范
@abstractmethod
def func(self):pass
# 可以访问,但是工作中千万不要用.
# print(A._A__age)
class A:
company_name = 'xxxx公司' # 静态变量(静态字段)
__iphone = '1353333xxxx' # 私有静态变量(私有静态字段)
def __init__(self,name,age): #特殊方法
self.name = name #对象属性(普通字段)
self.__age = age # 私有对象属性(私有普通字段)
def func1(self): # 普通方法
pass
def __func(self): #私有方法
print(666)
@classmethod # 类方法
def class_func(cls):
""" 定义类方法,至少有一个cls参数 """
print('类方法')
@staticmethod #静态方法
def static_func():
""" 定义静态方法 ,无默认参数"""
print('静态方法')
@property # 属性
def prop(self):
pass
class Parent:
def __func(self):
print('in Parent func')
def __init__(self):
self.__func()
class Son(Parent):
def __func(self):
print('in Son func')
son1 = Son()
# 运行结果是?
将方法伪装成一个属性,代码上没有什么提升,只是更合理.
@property ***
@属性名.setter **
@属性名.deleter *
静态方法使用的关键字是@staticmethod,通过在方法前追加此装饰器该方法就属于一个静态方法,静态方法个人理解为它既不依赖实例对象也不依赖于类,它只是需要一个载体即可,所以无论是通过类对象直接调用还是实例对象进行调用都是可以的,需要注意的是在静态方法中无法使用实例属性和方法。所以在日常过程中如果有一个方法实现的功能比较独立的时候就可以考虑使用静态方法实现
# 类名.名字
# getattr(类名,'名字')
# 对象名.名字
# getattr(对象,'名字')
# 模块名.名字
# import 模块
# getattr(模块,'名字')
# 自己文件.名字
# import sys
# getattr(sys.modules['__main__'],'名字')
# __call__ 相当于 对象() flask框架
# __len__ len(obj)
# __new__ 特别重要 开辟内存空间的 类的构造方法
# __str__ str(obj),'%s'%obj,print(obj)
# 所有的双下方法 没有 需要你在外部直接调用的
# 而是总有一些其他的 内置函数 特殊的语法 来自动触发这些 双下方法
# __new__ # ==> 构造方法
# 1.开辟一个空间,属于对象的
# 2.把对象的空间传给self,执行init
# 3.将这个对象的空间返回给调用者
# __init__ # ==> 初始化方法
# print一个对象相当于调用一个对象的__str__方法
# str(obj),相当于执行obj.__str__方法
# '%s'%obj,相当于执行obj.__str__方法
class Single:
__ISINCTANCE = None
def __new__(cls, *args, **kwargs):
if not cls.__ISINCTANCE:
cls.__ISINCTANCE = object.__new__(cls)
return cls.__ISINCTANCE
def __init__(self,name,age):
self.name = name
self.age = age
s1 = Single('alex',83)
s2 = Single('taibai',40)
class A:
def __del__(self):
# 析构方法 del A的对象 会自动触发这个方法
print('执行我了')
a = A()
del a # 对象的删除 del
print(a)
class B:
def __getitem__(self, item):
return getattr(self,item)
def __setitem__(self, key, value):
setattr(self,key,value*2)
def __delitem__(self, key):
delattr(self,key)
b = B()
# b.k2 = 'v2'
# print(b.k2)
b['k1'] = 'v1' # __setitem__
print(b['k1']) # __getitem__
del b['k1'] # __delitem__
print(b['k1'])
员工管理系统
对象的属性 : 姓名 性别 年龄 部门
内部转岗 python开发 - go开发
姓名 性别 年龄 新的部门
600个员工
如果几个员工对象的姓名和性别相同,这是一个人。请对这600个员工做去重?
class Employee:
def __init__(self,name,age,sex,partment):
self.name = name
self.age = age
self.sex = sex
self.partment = partment
def __hash__(self):
return hash('%s%s'%(self.name,self.sex))
def __eq__(self, other):
if self.name == other.name and self.sex == other.sex:
return True
employ_lst = []
for i in range(200):
employ_lst.append(Employee('alex',i,'male','python'))
for i in range(200):
employ_lst.append(Employee('wusir',i,'male','python'))
for i in range(200):
employ_lst.append(Employee('taibai', i, 'male', 'python'))
# print(employ_lst)
employ_set = set(employ_lst)
for person in employ_set:
print(person.__dict__)
#{'name': 'alex', 'age': 0, 'sex': 'male', 'partment': 'python'}
#{'name': 'taibai', 'age': 0, 'sex': 'male', 'partment': 'python'}
#{'name': 'wusir', 'age': 0, 'sex': 'male', 'partment': 'python'}
#进程已结束,退出代码0
# 分类 管理方法
# 节省内存
# 提供更多的功能
# import 导入 # 要导入一个py文件的名字,但是不加.py后缀名
# import这个语句相当于什么??? import这个模块相当于执行了这个模块所在的py文件
# 模块可以被多次导入么? 一个模块不会被重复导入,即使重复写了多次也只执行一次
# 模块的名称必须满足变量的命名规范,一般情况下 模块都是小写字母开头的名字
# 模块的重命名 import my_module as m
# 在import之后再修改这个被导入的模块,程序是感知不到的
# 如何反射本模块的变量:getattr(sys.modules[__name__],'要反射的变量名')
# 在编写py程序的时候,所有不在函数和类中封装的内容都应该写在 if __name__ == '__main__':下面
# sys.models 存储了所有导入的文件的名字和这个文件的内存地址
# 在模块的导入中,不要产生循环引用问题,如果发生循环导入了就会报错,就会发现明明写在这个模块中的方法,却显示找不到
# * 和 __all__ 的相关性 __all__ 可以控制*的导入情况
# PEP8规范
# 所有的模块导入都应该尽量放在这个文件的开头
# 模块的导入也是有顺序的
# 先导入内置模块
# 再导入第三方模块
# 最后导入自定义模块