第二十六天对属性的修改:
1.怎么进行以后大程序的书写:
首先要创建一个core的包:然后再创建一个core的py文件用于主要函数的书写
2.然后在创建一个db的包用于存放用户所写的数据:
3再创建一个conf的包,然后存放文件打开的路径:即把db中放数据的文件路径放到conf。py文件中
4.再创建一个bin文件包里面建立一个statt的py文件
.对私有属性和方法的查看方法:
class Person: def __init__(self,name,sex): self.name=name self.__sex=sex def get_sex(self): #查看私有属性的方法 return self.__sex jin=Person('jin','不想') print(jin.get_sex()) 结果为 不想
6.对私有属性的修改方法:
class Person: def __init__(self,name,sex): self.name=name self.__sex=sex def get_sex(self): #查看私有属性的方法 return self.__sex def set_sex(self,new_sex): #对私有属性进行修改的方法: if type(new_sex)is str and not new_sex.isdigit(): self.__sex=new_sex else: print('你输入的不合法') jin=Person('jin','不想') print(jin.get_sex()) jin.set_sex('2') jin.set_sex('小九年') print(jin.get_sex()) 结果为 不想 你输入的不合法 小九年
7.如果父类中有私有属性和方法,那么子类可以继承吗?
class Person: __key=123 class Fll(Person): def __init__(self): print(Person.__key) jin=Fll() 结果为 Traceback (most recent call last): File "D:/python练习程序/第二十六天/封装.py", line 36, in <module> jin=Fll() File "D:/python练习程序/第二十六天/封装.py", line 35, in __init__ print(Person.__key) AttributeError: type object 'Person' has no attribute '_Fll__key'
通过上述的报错我们可以得出:父类中的私有属性没有办法指向子类,也就是说子类无法继承父类的私有属性和方法
8,总结:私有属性使用的途径:(说实话都是进行属性和方法的保护)
1.隐藏起来,这个属性不想被外面的对象调用
2.这个属性的值不想被随意进行改变
3.这个属性和方法,不想被子类进行继承
9.内置函数·1property 把一下听起来名字像名词但是定义为类的方法伪装成属性的内置函数:
案例一:求圆的面积和周长为例:周长和面积挺起来是名词,属于属性但是我们定义成方法,像得到某个东西或者攻击这种才是动词属于方法:
from math import pi class Circle: def __init__(self,r): self.r=r @property #调用此内置函数可以让某些类的方法伪装成属性来使用,而且此方法的括号 def permeter(self):#中不允许有新的变量传入 return 2*pi*self.r @property def area(self): return (self.r**2)*pi c1=Circle(4) print(c1.permeter) print(c1.area) 结果为 25.132741228718345 50.26548245743669
10.既然上述把方法变成了属性,在类中属性的值是可以进行修改的,那么这个伪装的属性可以进行修改吗:
答:是不能的,他只是通过装饰器伪装成一个属性,在程序内部其实还是执行的类的方法:
11.一个计算·Bim指数的方法:把他的方法用属性来进行表示:
class Bim: def __init__(self,weight,height): self.weight=weight self.height=height @property def get_bim(self): return self.weight/(self.height**2) b1=Bim(80,1.78) print(b1.get_bim) 结果为 25.24933720489837 25.24933720489837
12.如果把某个方法变成了属性,
class Person: def __init__(self,name): self.__name=name @property def name(self): return self.__name+'sb' tiger=Person('老虎') print(tiger.name) 结果为 C:\pycharm\python.exe D:/python练习程序/第二十六天/封装.py 老虎sb
13.方法伪装成属性之后对象就没哟办法再去调用此方法,如果使用就会报错
class Person: def __init__(self,name): self.__name=name @property def name(self): return self.__name+'sb' tiger=Person('老虎') print(tiger.name) tiger.name()#如果在使用此对象来调用此方法会报错 结果为 老虎sb Traceback (most recent call last): File "D:/python练习程序/第二十六天/封装.py", line 67, in <module> tiger.name() TypeError: 'str' object is not callable
14可以使用setter方法来进行重命名:
class Person: def __init__(self,name): self.__name=name @property def name(self): return self.__name+'sb' @name.setter #使用此方法可以让伪装方法的属性进行赋值#并且命名的名字要和属性一致 def name(self,new_name):#如果不一致就会报错 self.__name=new_name tiger=Person('老虎') print(tiger.name) tiger.name='全班' print(tiger.name) 结果为 老虎sb 全班sb
15如果某个超市进行打折活动,想要把所有商品进行打折,这个程序用类怎么进行写:
class Good: discount=0.5 def __init__(self,name,price): self.name=name self.__price=price def price(self): return Good.discount*self.__price apple1=Good('apple',5 ) print(apple1.price) 结果为 <bound method Good.price of <__main__.Good object at 0x000002073FE36A58>>
这个为地址,也就是说这一个
class Good: discount=0.5 def __init__(self,name,price): self.name=name self.__price=price @property def price(self): return Good.discount*self.__price apple1=Good('apple',5 ) print(apple1.price) 结果为 2.5
16.对伪装的类进行删除操作:
class Person: def __init__(self,name): self.__name=name @property def name(self): return self.__name+'sb' @name.setter #使用此方法可以让伪装方法的属性进行赋值#并且命名的名字要和属性一致 def name(self,new_name):#如果不一致就会报错 self.__name=new_name @name.deleter def name(self): #第五个 del self.__name tiger=Person('老虎') print(tiger.name) tiger.name='全班' print(tiger.name) del tiger.name #这个指令会跳到第五个类的方法,执行这里面的语句
通过下面这个程序看此方法的执行过程:
class Person: def __init__(self,name): self.__name=name @property def name(self): return self.__name+'sb' @name.setter #使用此方法可以让伪装方法的属性进行赋值#并且命名的名字要和属性一致 def name(self,new_name):#如果不一致就会报错 self.__name=new_name @name.deleter def name(self): #第五个 print('执行了删除操作') tiger=Person('老虎') print(tiger.name) tiger.name='全班' print(tiger.name) del tiger.name #这个指令会跳到第五个类的方法,执行这里面的语句 结果为 老虎sb 全班sb 执行了删除操作
17.如果对上面商品打折的折扣进行修改:
class Good: __discount=0.5 def __init__(self,name,price): self.name=name self.__price=price @property def price(self): return Good.__discount*self.__price def change_discount(self,new_discount): Good.__discount=new_discount apple1=Good('apple',5 ) print(apple1.price) Good.change_discount(0.4) print(apple1.price) 结果为 Traceback (most recent call last): 2.5 File "D:/python练习程序/第二十六天/封装.py", line 89, in <module> Good.change_discount(0.4) TypeError: change_discount() missing 1 required positional argument: 'new_discount'
通过上述程序我们可以看出此错误为我们少给了一个量:又看了函数我们没有用到self量所以我们可以把这一个量删了:
class Good: __discount=0.5 def __init__(self,name,price): self.name=name self.__price=price @property def price(self): return Good.__discount*self.__price def change_discount(new_discount): Good.__discount=new_discount apple1=Good('apple',5 ) print(apple1.price) Good.change_discount(0.4) print(apple1.price) 结果为 C:\pycharm\python.exe D:/python练习程序/第二十六天/封装.py 老虎sb 全班sb 执行了删除操作 2.5 2.0
进行修改之后:如果使用类的方法那:
class Good: __discount=0.5 def __init__(self,name,price): self.name=name self.__price=price @property def price(self): return Good.__discount*self.__price @classmethod #使用此方法就是将对象中的方法变成类的方法,这样就可以使用类直接被调用 def change_discount(cls,new_discount):#不需要依靠任何对象 Good.__discount=new_discount apple1=Good('apple',5 ) print(apple1.price) Good.change_discount(0.4) print(apple1.price) 结果为 C:\pycharm\python.exe D:/python练习程序/第二十六天/封装.py 老虎sb 全班sb 执行了删除操作 2.5 2.0
总结:使用此方法的环境:当这个方法中只涉及到静态属性的时候,就应该使用classmethod来装饰这个方法
18.在java中所有的程序都是面向对象的:
class Login: def __init__(self,name,passwd): self.name=name self.passwd=passwd def login(self): pass @staticmethod #静态方法 def get_use(): usr=input('请输入用户名') passwd=input('请输入用户密码') Login(usr,passwd) Login.get_use() 结果为 请输入用户名jfdkj 请输入用户密码12344
在完全面向对象的过程中,如果一个函数即和对象没有关系,也和类没有关系那么就用staticmethod将这个函数变成一个静态的方法
19.总结:
类的静态方法和属性:都是可以被类进行调用的
对象可以调用类方法和静态方法吗 是可以的但是一般推荐使用类名进行调用
类方法 默认有一个参数就是cls 代表这一个类
静态方法 没有默认的参数,就是函数一样
20
21.抽象和继承:
22.反射:就是将类或者对象中的方法通过字符串的方式取出:
1。在这之前我们学过去除字符串的方法:
name='alex' eval('print(name)') 结果为 alex
class A: def func(self): print('哈哈哈') a=A() a.name='alex' #给对象添加一个名字的属性 ret=getattr(a,'name') #使用反射的方法返回属性 print(ret) print(A.__dict__) print(a.__dict__) ret1=getattr(a,'func') #这一步得到是对象方法的地址 print(ret1) ret1() 结果为 alex {'__module__': '__main__', 'func': <function A.func at 0x00000159BD3C5620>, '__dict__': <attribute '__dict__' of 'A' objects>, '__weakref__': <attribute '__weakref__' of 'A' objects>, '__doc__': None} {'name': 'alex'} <bound method A.func of <__main__.A object at 0x00000159BD3D5F60>> 哈哈哈
23.反射里面也可以使用静态方法和类方法:
class A: __key=122 @staticmethod def func(): #静方法不需要传入参数 print('哈哈哈') @classmethod def func1(cls): return A.__key a=A() ret=getattr(A,'func') #使用反射的方法返回属性 print(ret()) ret1=getattr(A,'func1') #这一步得到是对象方法的地址 print(ret1) print(ret1())#两种类型都是通过类名进行调换的 结果为 哈哈哈 None <bound method A.func1 of <class '__main__.A'>> 122
24.hasatter:#用于判断如果有返回值则返回True否则返回False
class A: __key=122 @staticmethod def func(): #静方法不需要传入参数 print('哈哈哈') @classmethod def func1(cls): return A.__key a=A() ret=hasattr(A,'func') #用于判断如果有返回值则返回True否则返回False print(ret) 结果为 True
25.后期http经常使用: