python中的方法不能重名,定义了多个重名都只有最后一个有效
python是动态语言,可以动态增加方法
class Person: def work(self): print('work') def play_game(s): print('{0}paly'.format(s)) def work2(s): print('好好学习') Person.play = play_game # 将play_game这个方法赋给Persen.play Person.work2 = work2 # 将work2这个方法赋给work2 p = Person() p.work() p.play() #Person.play(p),所以这里是不用给参数的 p.work2()
方法本质和属性一样,都是对象
class Employee: __company = 'swjtu' #私有类属性 def __init__(self,name,age): self.name = name self.__age = age #私有属性 def __work(self): #私有方法 print('work hard') print('内部调私有属性,年龄{0}'.format(self.__age)) e = Employee('selene',18) print(e.name) print(e._Employee__age) #私有属性外部访问 e._Employee__work() #私有方法外部访问 print(Employee._Employee__company) #私有类属性外部访问
@property装饰器将一个方法的调用变成一个属性的调用
使用:
class Employee: @property def salary(self): print('salary run...') return 100 emp1 = Employee() print(emp1.salary)#作为属性的调用,不能赋值 #emp1.salary = 1000会报错
两端代码效果一样
#用私有属性控制薪水录入错误 class Employee2: def __init__(self, name, salary): self.__name = name self.__salary = salary #属性私有 def get_salary(self):#用这个方法给私有属性赋值 return self.__salary def set_salary(self,salary): if 1000<salary<50000: self.__salary = salary else: print('录入错误') emp2 = Employee2('selene',30000) print(emp2.get_salary()) emp2.set_salary(2000) print(emp2.get_salary())
#@property class Employee3: def __init__(self, name, salary): self.name = name self.__salary = salary #属性私有 @property def salary(self): #用这个方法给私有属性赋值,相当于get_salary方法 return self.__salary @salary.setter #针对salar属性的设置,相当于set_salary方法 def salary(self,salary): if 2000<salary<50000: self.__salary = salary else: print('录入错误') emp3 = Employee3('selene',40000) print(emp3.salary) emp3.salary = 10000 #这里可以赋值成功!!!!!!! print(emp3.salary)
class Person: def __init__(self,name,age): self.name = name self.__age = age #父类私有属性,子类继承了但不能直接用 def say_age(self): print('jiecheng') class Student(Person): def __init__(self,name,age,score): Person.__init__(self,name,age) #直接写self.name = name也行,这里是显示调用 self.score = score print('Student的继承关系',Student.mro()) #查看Student的继承关系 s = Student('selene',18,100) s.say_age() #继承了父类的方法 print(dir(s)) #查看s的所有属性 print('父类非私有属性:',s.name) print('父类私有属性:',s._Person__age) #父类的私有属性需要这样调用,不能直接使用 ''' Student的继承关系 [<class '__main__.Student'>, <class '__main__.Person'>, <class 'object'>] jiecheng ['_Person__age', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'name', 'say_age', 'score'] 父类非私有属性: selene 父类私有属性: 18 '''
子类继承了父类,可以重新定义父类的方法,叫方法重写
class Person: def __init__(self,name,age): self.name = name self.__age = age def say_age(self): print('print my age:',self.__age) def say_name(self): print('print my name:', self.name) class Student(Person): def __init__(self,name,age,score): Person.__init__(self,name,age) #直接写self.name = name也行,这里是显示调用 self.score = score def say_name(self): print('我的名字是:',self.name) def say_age(self): print('我的年龄是:',self._Person__age)#name是父类的私有属性 s = Student('selene',18,100) s.say_name() s.say_age() ''' 我的名字是: selene 我的年龄是: 18 '''
class_name.mor()
object类是其他所有类的父类
#重写object的_str_() class Person: def __init__(self,name): self.name = name def __str__(self): return '名字是:{0}'.format(self.name) p = Person('selene') print(p) ''' 没有_str_时的结果: <__main__.Person object at 0x000002096990DB08> 有_str_时的结果: 名字是:selene '''
super()获得父类的定义
class A: def say(self): print('A:',self) class B(A): def say(self): A.say(self)#可以换成super().say(),获得父类的定义对象 print('B:',self) B().say() '''结果: A: <__main__.B object at 0x00000272A8B11108> B: <__main__.B object at 0x00000272A8B11108> '''
class Man: def dinner(self): print('吃饭') class Chinese(Man): def dinner(self): print('筷子') class English(Man): def dinner(self): print('叉子') def manEat(m):#形参m需要传一个类 if isinstance(m,Man):#isinstance()判断对象是否是一个一已知的类型,如isintance(2,int),返回true,且考虑继承 m.dinner() else: print('no dinner') #同一方法调用,由于对象不同可能产生不同的行为 manEat(Chinese()) manEat(English()) '''结果 筷子 叉子 '''
#重载运算符 class Person: def __init__(self,name): self.name = name def __add__(self,other):#重写加法 if isinstance(other,Person): return '{0}--{1}'.format(self.name,other.name) else: print('不是同类对象,不能相加') def __mul__(self,other):#重写乘法 if isinstance(other,int): return self.name*other else: return '不是整数倍,不能相乘' p1 = Person('bai') p2 = Person('selene') x = p1 + p2 y = p1*3 print(x,y) '''结果 bai--selene baibaibai '''
class A: def aa(self): print('AA') class B: def bb(self): print('BB') class C(A,B): def __init__(self,name): self.name = name def cc(self): print('cc') c = C('selene') print('获得c的所有属性',dir(c)) print('获得c添加的属性',c.__dict__) print('获得c的类',c.__class__) print('获得C的父类(多个)',C.__bases__) print('获得C的类层次结构',C.mro()) '''结果 获得c的所有属性 ['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'aa', 'bb', 'cc', 'name'] 获得c添加的属性 {'name': 'selene'} 获得c的类 <class '__main__.C'> 获得C的父类(多个) (<class '__main__.A'>, <class '__main__.B'>) 获得c的类 [<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>] '''
#使用继承 class A1: def say_a1(self): print('a1a1') class B1(A1): pass b1 = B1() b1.say_a1() #使用组合 class A2: def say_a2(self): print('a2a2') class B2: def __init__(self,a): self.a = a a2 = A2() b2 = B2(a2) b2.a.say_a2() '''结果 a1a1 a2a2 '''
class CarFactory: def create_car(self,brand): if brand == 'Benz': return Benz() elif brand =='BMW': return BMW() elif brand =='BYD': return BYD() else: return 'unknown brand' class Benz: pass class BMW: pass class BYD: pass factory = CarFactory() c1 = factory.create_car('BMW') print(c1)
确保一个类就只有一个对象
class MySingleton: _obj = None __init_flag = True def __new__(cls, *args, **kwargs): if cls._obj ==None:#若为空,则返回这个对象 cls._obj = object.__new__(cls) return cls._obj def __init__(self,name): if MySingleton.__init_flag: print('init...') self.name = name MySingleton.__init_flag = False a = MySingleton('aa') b = MySingleton('bb') print(a) print(b) '''结果 init... <__main__.MySingleton object at 0x00000182E01F1588> <__main__.MySingleton object at 0x00000182E01F1588> '''
#工厂模式和单例模式的整合 class CarFactory: _obj = None __init_flag = True def create_car(self,brand): if brand == 'Benz': return Benz() elif brand =='BMW': return BMW() elif brand =='BYD': return BYD() else: return 'unknown brand' def __new__(cls, *args, **kwargs): if cls._obj ==None:#若为空,则返回这个对象 cls._obj = object.__new__(cls) return cls._obj def __init__(self): if CarFactory.__init_flag: print('init...') CarFactory.__init_flag = False class Benz: pass class BMW: pass class BYD: pass factory = CarFactory() c1 = factory.create_car('BMW') c2 = factory.create_car('BYD') print(c1) print(c2) factory2 = CarFactory() print(factory) print(factory2) '''结果 <__main__.BMW object at 0x00000232A81D1C88> <__main__.BYD object at 0x00000232A81D1C48> <__main__.CarFactory object at 0x00000232A81D1C08> <__main__.CarFactory object at 0x00000232A81D1C08> '''