Python method parameter restricted class - python

I want to restrict a parameter within a set of options. If the function is called a parameter must be restricted to a couple of options.
This is what I have until now
class GetFileMethod:
URL = 'url'
ATTACHMENT = 'attachment'
class MailClient
def GetFile(self,method)
MailClient.GetFile(GetFileMethod.URL) #works ok, but
MailClient.GetFile("lalala") #should raise an error
Any suggestions?

def GetFile(self, method):
if method not in {'url','attachment'}:
raise ValueError
I would make GetFileMethod a method of the MailClient class and it will make life easier controlling the input.

Change your class MainClient to this:-
you need to check the value of method that you are providing in the namespace of the class GetFileMethod so that :-
GetFileMethod.__dict__.values()
class MailClient:
def GetFile(self, method):
if method in GetFileMethod.__dict__.values():
return 'Yes'
else:
return 'No'

Related

Python. How to take custom type objects from *args

I have the following method:
def _loginEventHandler(cmdID, *args):
if cmdID == Login.LOGIN_LOGED:
user = args[0]
print("User",user.userTypeID,"logged in")
that method is called like this from a different module:
user = User(nUserSelected)
_loginEventHandler(Login.LOGIN_LOGED,user)
the interpreter throws an AttributeError:
file "/main.py", line 79, in _loginEventHandler
print("User",user.userTypeID,"logged in")
AttributeError: 'tuple' object has no attribute 'userTypeID'
The question is what is the proper way of taking arguments from *args (specially if they are custom types like with "User") and why is it taking a tuple from args[0]
You didn't include self in the definition of the method. The first argument passed to a method is always the instance itself. That means that in your method, cmdID is taking the value of the instance, and the first element of args is actually the value of Login.LOGIN_LOGED, which is presumably a tuple.
So I tried to come up with a minimal version of the User class and a Login Enum. But I don't see any problems here. The output seems okay
from enum import Enum
class Login(Enum):
LOGIN_LOGED = 1
class User:
def __init__(self, userTypeID):
self.userTypeID = userTypeID
user = User(1)
_loginEventHandler(Login.LOGIN_LOGED, user)
which gives
('User', 1, 'logged in')

Python 3 static members

I am trying to achieve the following:
class A:
username = None
username = get_username()
def get_username(self):
if username is None:
try:
uname = os.environ["USER"]
except:
printf("Couldn't find a user name")
return uname
return username
Not sure how to achieve this. I'm sure I'm missing some "self." prefixes but this is the first time I'm working with python and static members.
In a sense I want a class with some members and functions to calculate values for these members but I don't want recalculations. I would also like these to be static functions and data members.
The problem is that the line "username = get_username()" the function hasn't already been defined. If I put username after the function then it's not
First, there's no reason to assign None to username if you're just going to reassign it immediately after.
Second, if you want the method to be a static method, you can't give it a self argument. And if you want a real static method, you have to declare it explicitly.
#staticmethod
def get_username():
if username is None:
...
Otherwise, you need an instance of the class (that self) to call it on, and you don't have one yet.
In Python 3, any regular method acts like a static method when called on the class, like an instance method when called on an instance. So, if you're sure you're never going to want to call a.get_username() on an instance a, you can skip the decorator. But you still need to get rid of the self parameter.
I think what you're actually trying to do is use a class variable to memoize the result of a static method. You can't do that, but you can use a class variable to memoize the result of a class method, which may be close enough. That would look like this:
class A:
username = None
#classmethod
def get_username(cls):
if cls.username is None:
try:
uname = os.environ["USER"]
except:
print("Couldn't find a user name")
else:
cls.username = uname
return cls.username
On the other hand, there's no good reason username has to be a class member. You can memoize by adding a member to the function, by passing a mutable default variable, or in various other ways which don't require infecting the class, and which allow you to leave get_username as a static method instead of a class method.
But really, the best solution is to find a memoization library on PyPI, in ActiveState's recipe list, etc., so you can just write this:
class A:
#memoize
#staticmethod
def get_username():
try:
return os.environ["USER"]
except:
print("Couldn't find a user name")
return None
Again, you can drop the #staticmethod if you're sure nobody's ever going to try to create an instance of A and call get_username on it.
if you don't want to lose the ability to refer to A.username, you can use class property with a little bit of metaclass:
class A(type):
def __new__(cls, name, bases, attrs):
# this allows B().username to also work
attrs['username'] = property(lambda s: s.__class__.username)
return type.__new__(cls, name, bases, attrs)
#property
def username(self):
if not hasattr(self, '_username'):
self._username = 'bar'
return self._username
class B(object):
__metaclass__ = A
print B.username
print B().username

Python pass instance of itself as an argument to another function

I have a UserModel class that will essentially do everything like login and update things.
I'm trying to pass the instance of itself (the full class) as an argument to another function of another class.
For example: (obviously not the code, but you get the idea)
from Car import CarFactory
class UserModel:
def __init__(self,username):
self.username = username
def settings(self,colour,age,height):
return {'colour':colour,'age':age,'height':height}
def updateCar(self,car_id):
c = CarFactory(car_id, <<this UserModel instance>>)
So, as you can see from the very last line above I would like to pass an instance of UserModel to the CarData class, so when within the CarData class I can access the UserModel.settings(), however, I am unsure of the syntax. I could of course just do:
c = CarFactory(car_id,self.settings)
Any help would be grateful appreciated.
Thanks
c = CarFactory(car_id, self)
doesnt work?
on a side note it would be self.settings() not self.settings ... unless you define settings to be a property

Referencing variable from static method inside another action in Pylons

I've got:
class ArticleController(SubbaseController):
def view(self):
c.referral = self.detect_referral.referrer
return render('/article.mako')
#staticmethod
def detect_referral():
referrer = request.META.get('HTTP_REFERRER', '')
I'm trying to reference the referrer inside of the view action from the detect_referral static method, but I keep getting: 'function' object has no attribute 'referrer' instead. Any ideas?
Also, is that the correct way to get the referrer?
You aren't returning the referrer from detect_referral, and detect_referral is not a property, so you cannot use that syntax.
class ArticleController(BaseController):
def view(self):
c.referral = self.detect_referral()
return render('/article.mako')
#staticmethod
def detect_referral():
return request.META.get('HTTP_REFERRER', '')
It's a local variable inside detect_referral(), and as such its lifetime is limited to the execution time of the method. Before the method is called and after the method returns local variables simply don't exist. (You don't even seem to call the method, so the local variable exists at no time of the execution of your program.)
Most probably you don't want a static method here. (You almost never want a static method in Python. I cannot remember that I ever used one.) Maybe all you need is a class attribute:
class ArticleController(SubbaseController):
referrer = request.META.get('HTTP_REFERRER', '')
def view(self):
c.referral = self.referrer
return render('/article.mako')
Note that the class body is executed once at class definition time.

Python: Problems mocking an instance

I am having problem mocking an object to test a descriptor.
This is the code of the descriptor:
class Text(object):
def __init__(self, default_value=u'', validators=[]):
self.validators = validators
self._value = default_value
def __set__(self, instance, value):
for validator in self.validators:
validator(value).validate()
this is the test:
def test_text_validator_raises_exception(self):
validator = Mock()
validator.validate.side_effect = ValidationError()
text = Text(validators=[validator])
self.assertRaises( ValidationError, text__set__, (text, '') )
Edit:
The function has () in the code I did a typo when copying the code.
The error I got was that set() takes exactly 3 arguments. But I noticed in the answers that I shouldn't pass a tuple as a last argument.
But It also isn't working when I called validator('').validate() inside the test function.
validator in Text is an object factory e.g., class object
validator in the test_.. function is used as a concrete instance -- the product of an object factory.
You should give to Text() something that returns objects with .validate method not the objects themselves:
def test_text_validator_raises_exception(self):
validator = Mock()
validator.validate.side_effect = ValidationError()
text = Text(validators=[Mock(return_value=validator)])
self.assertRaises(ValidationError, text.__set__, text, '')
I guess you need to put () after function name
Maybe the best way to mock an instance is just "You call yourself an instance?"
Seriously, though, def test_text_validator_raises_exception: should be def test_text_validator_raises_exception():
But what problem are you having with it, as the first commenter asked?

Categories

Resources